Skip to content

Commit

Permalink
throw exception when updating a subtemplate too resource (too many md…
Browse files Browse the repository at this point in the history
… to index)
  • Loading branch information
cmangeat committed Feb 16, 2024
1 parent 686a490 commit a5639b6
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 19 deletions.
34 changes: 34 additions & 0 deletions common/src/main/java/org/fao/geonet/exceptions/GNException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//=============================================================================
//=== Copyright (C) 2001-2023 Food and Agriculture Organization of the
//=== United Nations (FAO-UN), United Nations World Food Programme (WFP)
//=== and United Nations Environment Programme (UNEP)
//===
//=== This program is free software; you can redistribute it and/or modify
//=== it under the terms of the GNU General Public License as published by
//=== the Free Software Foundation; either version 2 of the License, or (at
//=== your option) any later version.
//===
//=== This program is distributed in the hope that it will be useful, but
//=== WITHOUT ANY WARRANTY; without even the implied warranty of
//=== MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
//=== General Public License for more details.
//===
//=== You should have received a copy of the GNU General Public License
//=== along with this program; if not, write to the Free Software
//=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
//===
//=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
//=== Rome - Italy. email: [email protected]
//==============================================================================
package org.fao.geonet.exceptions;

public class GNException extends RuntimeException {

public GNException(String msg) {
super(msg);
}

public GNException(String msg, Throwable cause) {
super(msg, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

package org.fao.geonet.kernel.datamanager.base;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
Expand All @@ -39,6 +40,7 @@
import org.fao.geonet.constants.Geonet;
import org.fao.geonet.constants.Params;
import org.fao.geonet.domain.*;
import org.fao.geonet.exceptions.GNException;
import org.fao.geonet.exceptions.UnAuthorizedException;
import org.fao.geonet.kernel.*;
import org.fao.geonet.kernel.datamanager.*;
Expand Down Expand Up @@ -139,6 +141,10 @@ public class BaseMetadataManager implements IMetadataManager {

@Autowired
private ApplicationContext _applicationContext;

@VisibleForTesting
public int maxMdsReferencingSubTemplate = 10000;

@PersistenceContext
private EntityManager _entityManager;

Expand Down Expand Up @@ -1317,7 +1323,10 @@ boolean hasReferencingMetadata(ServiceContext context, AbstractMetadata metadata

private void indexMdsReferencingSubTemplate(ServiceContext context, AbstractMetadata subTemplate) throws Exception {
StringBuilder query = new StringBuilder(String.format("xlink:*%s*", subTemplate.getUuid()));
SearchResponse response = this.searchManager.query(query.toString(), null, 0, 10000);
SearchResponse response = this.searchManager.query(query.toString(), null, 0, maxMdsReferencingSubTemplate);
if (response.getHits().getTotalHits().value > maxMdsReferencingSubTemplate) {
throw new GNException("Not implemented");
}
ArrayList<String> toIndex = new ArrayList<>();
response.getHits().forEach(consumer -> {
String consumerUuid = consumer.getId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
import org.elasticsearch.action.search.SearchResponse;
import org.fao.geonet.AbstractCoreIntegrationTest;
import org.fao.geonet.domain.AbstractMetadata;
import org.fao.geonet.kernel.datamanager.IMetadataManager;
import org.fao.geonet.exceptions.GNException;
import org.fao.geonet.kernel.datamanager.base.BaseMetadataIndexer;
import org.fao.geonet.kernel.datamanager.base.BaseMetadataManager;
import org.fao.geonet.kernel.search.EsSearchManager;
import org.fao.geonet.kernel.search.IndexingMode;
import org.fao.geonet.kernel.setting.SettingManager;
Expand All @@ -33,13 +34,15 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.when;

public class LocalXLinksUpdateDeleteTest extends AbstractIntegrationTestWithMockedSingletons {
@Autowired
private IMetadataManager metadataManager;
private BaseMetadataManager metadataManager;

@Autowired
private SettingManager settingManager;
Expand All @@ -60,29 +63,29 @@ public void setUp() throws Exception {

@Test
public void updateHasToRegisterReferrersForIndexation() throws Exception {
URL contactResource = AbstractCoreIntegrationTest.class.getResource("kernel/babarContact.xml");
Element contactElement = Xml.loadStream(contactResource.openStream());
AbstractMetadata contactMetadata = insertContact(contactElement);
AbstractMetadata vicinityMapMetadata = insertVicinityMap(contactMetadata);
assertEquals(1, countMetadataUsing(vicinityMapMetadata.getUuid(), "babar").getHits().getHits().length);
assertEquals(0, countMetadataUsing(vicinityMapMetadata.getUuid(), "momo").getHits().getHits().length);
Mockito.reset(metadataIndexer);

Xml.selectElement(contactElement, "gmd:individualName/gco:CharacterString", Arrays.asList(GMD, GCO)).setText("momo");
metadataManager.updateMetadata(serviceContext,
Integer.toString(contactMetadata.getId()),
contactElement,
false,
false,
null,
null,
false,
IndexingMode.full);
AbstractMetadata vicinityMapMetadata = updateASubtemplateUsedByOneMetadata();

ArgumentCaptor<List> toIndexCaptor = ArgumentCaptor.forClass(List.class);
Mockito.verify(metadataIndexer).batchIndexInThreadPool(Mockito.anyObject(), toIndexCaptor.capture());
assertTrue(toIndexCaptor.getValue().contains(Integer.toString(vicinityMapMetadata.getId())));
}

@Test
public void exceedMaxMdsReferencingSubTemplateThrowsException() {
Mockito.reset(metadataIndexer);
try {
metadataManager.maxMdsReferencingSubTemplate = 0;

assertThrows(GNException.class, () -> updateASubtemplateUsedByOneMetadata());

Mockito.verify(metadataIndexer, never()).batchIndexInThreadPool(Mockito.anyObject(), Mockito.anyList());
} finally {
metadataManager.maxMdsReferencingSubTemplate = 10000;
}
}

private SearchResponse countMetadataUsing(String mdUuid, String contactForResourceIndividual) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();

Expand Down Expand Up @@ -155,6 +158,27 @@ private AbstractMetadata insertContact(Element contactElement) throws Exception
return contactMetadata;
}

private AbstractMetadata updateASubtemplateUsedByOneMetadata() throws Exception {
URL contactResource = AbstractCoreIntegrationTest.class.getResource("kernel/babarContact.xml");
Element contactElement = Xml.loadStream(contactResource.openStream());
AbstractMetadata contactMetadata = insertContact(contactElement);
AbstractMetadata vicinityMapMetadata = insertVicinityMap(contactMetadata);
assertEquals(1, countMetadataUsing(vicinityMapMetadata.getUuid(), "babar").getHits().getHits().length);
assertEquals(0, countMetadataUsing(vicinityMapMetadata.getUuid(), "momo").getHits().getHits().length);

Xml.selectElement(contactElement, "gmd:individualName/gco:CharacterString", Arrays.asList(GMD, GCO)).setText("momo");
metadataManager.updateMetadata(serviceContext,
Integer.toString(contactMetadata.getId()),
contactElement,
false,
false,
null,
null,
false,
IndexingMode.full);
return vicinityMapMetadata;
}

static public class SpyFactory {
@Autowired
BaseMetadataIndexer baseMetadataIndexer;
Expand Down

0 comments on commit a5639b6

Please sign in to comment.