Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1285,8 +1285,17 @@ private void logSwitchover(final IndiciesInfo oldInfo, final String luckyServer)

}

public boolean delete(String indexName) {
return indexAPI.delete(indexName);
public boolean delete(final String indexName) {
final boolean deleted = indexAPI.delete(indexName);
if (deleted) {
try {
versionedIndicesAPI.removeByIndexName(indexName);
} catch (DotDataException e) {
Logger.error(this, "Index [" + indexName + "] was physically deleted but the " +
"indices DB row could not be removed: " + e.getMessage(), e);
}
}
return deleted;
}

public boolean optimize(List<String> indexNames) {
Expand Down
10 changes: 10 additions & 0 deletions dotCMS/src/main/java/com/dotcms/content/index/IndicesFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,14 @@ public interface IndicesFactory {
void insertIndexIfPresent(String indexName, String indexType,
String version) throws DotDataException;

/**
* Removes the {@code indicies} table row for the given index name.
* Handles both plain and {@code os::}-prefixed forms of the name so that
* callers do not need to know how the name is stored in the database.
*
* @param indexName the physical index name (with or without vendor tag)
* @throws DotDataException if the name is blank or a SQL error occurs
*/
void removeByIndexName(String indexName) throws DotDataException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public class IndicesFactoryImpl implements IndicesFactory {
"SELECT COUNT(*) as count FROM indicies WHERE index_version = ? AND index_version IS NOT NULL";
private static final String COUNT_INDICES_BY_VERSION_SQL =
"SELECT COUNT(*) as count FROM indicies WHERE index_version = ? AND index_version IS NOT NULL";
private static final String DELETE_INDEX_BY_NAME_SQL =
"DELETE FROM indicies WHERE index_name = ? OR index_name = ?";

@Override
public Optional<VersionedIndices> loadIndices(String version) throws DotDataException {
Expand Down Expand Up @@ -360,6 +362,24 @@ public void insertIndexIfPresent(String indexName, String indexType, String vers
}
}

@Override
public void removeByIndexName(final String indexName) throws DotDataException {
if (!UtilMethods.isSet(indexName)) {
throw new DotDataException("Index name cannot be null or empty");
}
// Always work from the bare name so we can reliably compute both DB forms
final String bareName = IndexTag.strip(indexName);
final String taggedName = IndexTag.OS.tag(bareName);
try {
final DotConnect dotConnect = new DotConnect();
final int deleted = dotConnect.executeUpdate(DELETE_INDEX_BY_NAME_SQL, bareName, taggedName);
Logger.info(this, "Removed " + deleted + " row(s) from indicies for index: " + bareName);
} catch (Exception e) {
Logger.error(this, "Failed to remove indicies row for index: " + bareName, e);
throw new DotDataException("Failed to remove indicies row for index: " + bareName, e);
}
}

/**
* Builds a VersionedIndicesInfo from legacy non-versioned database results.
* Expects results to have columns: index_name, index_type (no index_version)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,16 @@ public interface VersionedIndicesAPI {
*/
Optional<VersionedIndices> loadDefaultVersionedIndices() throws DotDataException;

/**
* Removes the {@code indicies} table row for the given index name.
* Handles both plain and {@code os::}-prefixed forms of the name so that
* callers do not need to know how the name is stored in the database.
*
* @param indexName the physical index name (with or without vendor tag)
* @throws DotDataException if the name is blank or a SQL error occurs
*/
void removeByIndexName(String indexName) throws DotDataException;

/**
* Clears all cached indices data.
* This should be called when indices are modified outside of this API
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,23 @@ public Optional<VersionedIndices> loadDefaultVersionedIndices() throws DotDataEx
return loadIndices(VersionedIndices.OPENSEARCH_3X);
}

/**
* {@inheritDoc}
*/
@WrapInTransaction
@Override
public void removeByIndexName(final String indexName) throws DotDataException {
Logger.debug(this, "Removing indices row for index: " + indexName);
indicesFactory.removeByIndexName(indexName);
// Flush all index-related caches so no stale names survive the deletion:
// 1. VersionedIndicesCache — our own versioned-index cache
cache.clearCache();
// 2. IndiciesCache — legacy (ES, non-versioned) index cache used by IndiciesFactory
CacheLocator.getIndiciesCache().clearCache();
// 3. ESQueryCache — cached search queries that may reference the deleted index name
CacheLocator.getESQueryCache().clearCache();
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,15 @@ public void createContentIndexAndDelete() throws Exception {

//Verify we just added two more indices
assertEquals(oldIndices, newIndices);

// Verify the indicies table has no orphan rows for the deleted indices
final DotConnect dc = new DotConnect();
dc.setSQL("SELECT COUNT(*) AS cnt FROM indicies WHERE index_name = ? OR index_name = ?");
dc.addParam(workingIndex);
dc.addParam(liveIndex);
final List<Map<String, Object>> rows = dc.loadResults();
assertEquals("indicies table must have no orphan rows after delete",
0L, Long.parseLong(rows.get(0).get("cnt").toString()));
}

/**
Expand Down
Loading