Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unique index creation error for schemas added via API #229

Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ public String addEntity(Shard shard, String userId, JsonNode rootNode, boolean s
entityId = registryDao.addEntity(graph, rootNode);
if (commitEnabled) {
dbProvider.commitTransaction(graph, tx);
entityParenter.ensureKnownParentNodesForSchema(rootNode);
entityParenter.loadDefinitionIndexForSchema(rootNode);
entityParenter.ensureIndexExists();
}
} finally {
if (tx != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.sunbirdrc.registry.util;

import com.fasterxml.jackson.databind.JsonNode;
import dev.sunbirdrc.registry.dao.VertexWriter;
import dev.sunbirdrc.registry.middleware.util.Constants;
import dev.sunbirdrc.registry.model.DBConnectionInfo;
Expand All @@ -26,6 +27,8 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import static dev.sunbirdrc.registry.Constants.Schema;

@Component("entityParenter")
public class EntityParenter {
private static Logger logger = LoggerFactory.getLogger(EntityParenter.class);
Expand Down Expand Up @@ -114,7 +117,51 @@ public void loadDefinitionIndex() {
}
indexHelper.setDefinitionIndexMap(indexMap);
}
public void loadDefinitionIndexForSchema(JsonNode schemaNode) {
Map<String, Boolean> indexMap = new ConcurrentHashMap<String, Boolean>();

String schemaName = schemaNode.fieldNames().next();

for (Map.Entry<String, ShardParentInfoList> entry : shardParentMap.entrySet()) {
String shardId = entry.getKey();
ShardParentInfoList shardParentInfoList = entry.getValue();
shardParentInfoList.getParentInfos().forEach(shardParentInfo -> {
Definition definition = definitionsManager.getDefinition(shardParentInfo.getName());
// Process only for the specific schema added through API
if (definition.getTitle().equals(schemaName)) {
Vertex parentVertex = shardParentInfo.getVertex();
List<String> indexFields = definition.getOsSchemaConfiguration().getIndexFields();
if (!indexFields.contains(uuidPropertyName)) {
indexFields.add(uuidPropertyName); // adds default field
}
List<String> indexUniqueFields = definition.getOsSchemaConfiguration().getUniqueIndexFields();
List<String> compositeIndexFields = IndexHelper.getCompositeIndexFields(indexFields);
List<String> singleIndexFields = IndexHelper.getSingleIndexFields(indexFields);

IndexFields indicesByDefinition = new IndexFields();
indicesByDefinition.setDefinitionName(definition.getTitle());
indicesByDefinition.setIndexFields(indexFields);
indicesByDefinition.setUniqueIndexFields(indexUniqueFields);
indicesByDefinition.setNewSingleIndexFields(indexHelper.getNewFields(parentVertex, singleIndexFields, false));
indicesByDefinition.setNewCompositeIndexFields(indexHelper.getNewFields(parentVertex, compositeIndexFields, false));
indicesByDefinition.setNewUniqueIndexFields(indexHelper.getNewFields(parentVertex, indexUniqueFields, true));

int nNewIndices = indicesByDefinition.getNewSingleIndexFields().size();
int nNewUniqIndices = indicesByDefinition.getNewUniqueIndexFields().size();
int nNewCompIndices = indicesByDefinition.getNewCompositeIndexFields().size();

boolean indexingComplete = (nNewIndices == 0 && nNewUniqIndices == 0 && nNewCompIndices == 0);
indexHelper.updateDefinitionIndex(shardId, definition.getTitle(), indexingComplete);
logger.info("On loadDefinitionIndex for Shard:" + shardId + " definition: {} updated index to {} ",
definition.getTitle(), indexingComplete);

definitionIndexFields.put(indicesByDefinition.getDefinitionName(), indicesByDefinition);
}
});
}

indexHelper.setDefinitionIndexMap(indexMap);
}
/**
* Creates the parent vertex in all the shards for all default definitions
*
Expand Down Expand Up @@ -167,6 +214,59 @@ public Optional<String> ensureKnownParenters() {
return result;
}

public Optional<String> ensureKnownParentNodesForSchema(JsonNode schemaNode) {
logger.info("Start - ensure parent node for defined schema");
Optional<String> result;

dbConnectionInfoList.forEach(dbConnectionInfo -> {
logger.info("Starting to parents for {} definitions in shard {}", defintionNames.size(),
dbConnectionInfo.getShardId());
DatabaseProvider dbProvider = dbProviderFactory.getInstance(dbConnectionInfo);
try {
try (OSGraph osGraph = dbProvider.getOSGraph()) {
Graph graph = osGraph.getGraphStore();
List<ShardParentInfo> shardParentInfoList = new ArrayList<>();
try (Transaction tx = dbProvider.startTransaction(graph)) {

List<String> parentLabels = new ArrayList<>();
if(schemaNode.get(Schema)==null && schemaNode.fieldNames().next()!=null) {
String name = schemaNode.fieldNames().next();
defintionNames.forEach(defintionName -> {
if (defintionName.contains(name)) {
String parentLabel = ParentLabelGenerator.getLabel(defintionName);
parentLabels.add(parentLabel);

VertexWriter vertexWriter = new VertexWriter(graph, dbProvider, uuidPropertyName);
Vertex v = vertexWriter.ensureParentVertex(parentLabel);

ShardParentInfo shardParentInfo = new ShardParentInfo(defintionName, v);
shardParentInfo.setUuid(dbProvider.getId(v));
shardParentInfoList.add(shardParentInfo);
}
});


ShardParentInfoList valList = new ShardParentInfoList();
valList.setParentInfos(shardParentInfoList);

shardParentMap.put(dbConnectionInfo.getShardId(), valList);

dbProvider.commitTransaction(graph, tx);
}
}
logger.info("Ensured parents for {} definitions in shard {}", defintionNames.size(),
dbConnectionInfo.getShardId());
}
} catch (Exception e) {
logger.error("Can't ensure parents for definitions " + e);
}
});

logger.info("End - ensure parent node for defined schema");
result = Optional.empty();
return result;
}

/**
* Gets a known parent id
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,38 @@
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import dev.sunbirdrc.pojos.AsyncRequest;
import dev.sunbirdrc.pojos.SunbirdRCInstrumentation;
import org.mockito.ArgumentMatchers;
import dev.sunbirdrc.registry.exception.RecordNotFoundException;
import dev.sunbirdrc.registry.helper.RegistryHelper;
import dev.sunbirdrc.registry.model.DBConnectionInfoMgr;
import dev.sunbirdrc.registry.service.FileStorageService;
import dev.sunbirdrc.registry.service.ICertificateService;
import dev.sunbirdrc.registry.transform.*;
import dev.sunbirdrc.registry.util.DefinitionsManager;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import dev.sunbirdrc.registry.util.ViewTemplateManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import org.springframework.http.HttpHeaders;
import javax.servlet.http.HttpServletRequest;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;

import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@WebMvcTest({RegistryEntityController.class})
Expand Down