package com.constellio.sdk.tests; import com.constellio.data.dao.dto.records.RecordDTO; import com.constellio.data.dao.dto.records.RecordsFlushing; import com.constellio.data.dao.dto.records.TransactionDTO; import com.constellio.data.dao.services.bigVault.LazyResultsIterator.LazyRecordDTOResultsIterator; import com.constellio.data.dao.services.records.RecordDao; import com.constellio.data.utils.LangUtils; import com.constellio.data.utils.LangUtils.ListComparisonResults; import com.constellio.data.utils.LangUtils.MapComparisonResults; import com.constellio.data.utils.LangUtils.ModifiedEntry; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.solr.common.params.ModifiableSolrParams; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.*; import java.util.Map.Entry; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; public class SolrSDKToolsServices { RecordDao recordDao; public SolrSDKToolsServices(RecordDao recordDao) { this.recordDao = recordDao; } public void flushAndDeleteContentMarkers() throws Exception { recordDao.flush(); recordDao.removeOldLocks(); ModifiableSolrParams deleteMarkers = new ModifiableSolrParams(); deleteMarkers.set("q", "type_s:marker"); deleteMarkers.set("fq", "-schema_s:*"); recordDao.execute(new TransactionDTO(RecordsFlushing.NOW).withDeletedByQueries(deleteMarkers)); } public VaultSnapshot snapshot() { Map<String, Map<String, Object>> dataSnapshot = new HashMap<>(); Set<String> ids = new HashSet<>(); ModifiableSolrParams params = new ModifiableSolrParams(); params.set("q", "*:*"); params.add("fq", "-type_s:marker"); params.add("fq", "-id:lock__*"); for (Iterator<RecordDTO> iterator = new LazyRecordDTOResultsIterator(recordDao, params, 100); iterator.hasNext(); ) { RecordDTO record = iterator.next(); if (!record.getId().endsWith("ZZ")) { ids.add(record.getId()); dataSnapshot.put(record.getId(), toValue(record)); } } return new VaultSnapshot(ids, dataSnapshot); } // public List<RecordDTO> getRecords(int start, int end) { // // ModifiableSolrParams params = new ModifiableSolrParams(); // params.set("q", "*:*"); // params.set("start", "" + start); // params.set("sort", "id asc"); // params.set("rows", "" + end); // params.add("fq", "-type_s:marker"); // params.add("fq", "-id:lock__*"); // // List<RecordDTO> recordDTOs = recordDao.searchQuery(params); // // return recordDTOs; // } public long getRecordsCount() { ModifiableSolrParams params = new ModifiableSolrParams(); params.set("q", "*:*"); params.set("rows", "1"); params.add("fq", "-type_s:marker"); params.add("fq", "-id:lock__*"); return recordDao.nativeQuery(params).getResults().getNumFound(); } public Map<String, Object> toValue(RecordDTO record) { Map<String, Object> values = new HashMap<>(); for (Entry<String, Object> entry : record.getFields().entrySet()) { String fieldKey = entry.getKey(); if (!fieldKey.equals("_version_")) { Object value = record.getFields().get(fieldKey); if (value != null && (!(value instanceof List) || !((List) value).isEmpty())) { values.put(fieldKey, value); } } } for (Entry<String, Object> entry : record.getCopyFields().entrySet()) { String fieldKey = entry.getKey(); Object value = record.getCopyFields().get(fieldKey); if (value != null && (!(value instanceof List) || !((List) value).isEmpty())) { values.put(fieldKey, value); } } return values; } public void writeSnapshotToFile(VaultSnapshot vaultSnapshot, File file) throws IOException { BufferedWriter bufferedWriter = null; try { bufferedWriter = new BufferedWriter(new FileWriter(file)); List<String> ids = new ArrayList<>(vaultSnapshot.ids); Collections.sort(ids); for (String id : ids) { String fieldsString = toString(vaultSnapshot.datas.get(id)); bufferedWriter.write(fieldsString); bufferedWriter.newLine(); } bufferedWriter.flush(); } finally { IOUtils.closeQuietly(bufferedWriter); } } private String toString(Map<String, Object> data) { List<String> fields = new ArrayList<>(data.keySet()); Collections.sort(fields); StringBuilder stringBuilder = new StringBuilder(); for (String field : fields) { stringBuilder.append(field); stringBuilder.append("="); stringBuilder.append(data.get(field)); stringBuilder.append("\t"); } return stringBuilder.toString(); } public static class VaultSnapshot { Set<String> ids = new HashSet<>(); Map<String, Map<String, Object>> datas = new HashMap<>(); private VaultSnapshot(Set<String> ids, Map<String, Map<String, Object>> datas) { this.ids = ids; this.datas = datas; } } public void ensureSameSnapshots(String message, VaultSnapshot snapshotBeforeReindexation, VaultSnapshot snapshotAfterReindexation) { ListComparisonResults<String> idsComparison = LangUtils .compare(snapshotBeforeReindexation.ids, snapshotAfterReindexation.ids); StringBuilder idsComparisonMessage = new StringBuilder(); if (!idsComparison.getNewItems().isEmpty()) { idsComparisonMessage .append("\n\t* Created documents : " + StringUtils.join(idsComparison.getNewItems(), ",")); } if (!idsComparison.getRemovedItems().isEmpty()) { idsComparisonMessage .append("\n\t* Removed documents : " + StringUtils.join(idsComparison.getRemovedItems(), ",")); } if (idsComparisonMessage.length() > 0) { fail(message + idsComparisonMessage + "\n\n"); } boolean isSameIds = snapshotBeforeReindexation.ids.size() == snapshotAfterReindexation.ids.size(); if (isSameIds) { int matches = 0; for (String id : snapshotBeforeReindexation.ids) { if (snapshotAfterReindexation.ids.contains(id)) { matches++; } } isSameIds = snapshotBeforeReindexation.ids.size() == matches; } String[] idsAfterReindexation = snapshotAfterReindexation.ids.toArray(new String[0]); if (!isSameIds) { assertThat(snapshotBeforeReindexation.ids) .containsOnly(idsAfterReindexation) .containsOnlyOnce(idsAfterReindexation); } for (String id : idsAfterReindexation) { Map<String, Object> dataBefore = snapshotBeforeReindexation.datas.get(id); Map<String, Object> dataAfter = snapshotAfterReindexation.datas.get(id); MapComparisonResults<String, Object> results = LangUtils.compare(dataBefore, dataAfter); StringBuilder sb = new StringBuilder(); for (String removedKey : results.getRemovedEntries()) { sb.append( "\n\t* The field '" + removedKey + "' with value '" + dataBefore.get(removedKey) + "' was removed"); } for (String addedKey : results.getNewEntries()) { sb.append("\n\t* The field '" + addedKey + "' with value '" + dataAfter.get(addedKey) + "' was added"); } for (ModifiedEntry<String, Object> entry : results.getModifiedEntries()) { if(!entry.getKey().equals("jasperfile_s")) { sb.append("\n\t* The field '" + entry.getKey() + "' with value '" + entry.getValueBefore() + "' was modified to '" + entry.getValueAfter() + "'"); } } if (sb.length() > 0) { fail(message + "\nModifications in document '" + id + " : " + sb + "\n\n"); } } } }