Skip to content

Commit

Permalink
Bug fix for missing tenant id
Browse files Browse the repository at this point in the history
  • Loading branch information
NavidMitchell committed Jan 7, 2025
1 parent 8b0ba10 commit d6a1f1f
Showing 1 changed file with 25 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import io.opentelemetry.instrumentation.annotations.WithSpan;
import org.apache.commons.lang3.tuple.Pair;
import org.kinotic.continuum.idl.api.schema.decorators.C3Decorator;
import org.kinotic.structures.api.config.StructuresProperties;
import org.kinotic.structures.api.domain.idl.decorators.AutoGeneratedIdDecorator;
import org.kinotic.structures.api.domain.idl.decorators.IdDecorator;
import org.kinotic.structures.api.domain.EntityContext;
import org.kinotic.structures.api.domain.Structure;
import org.kinotic.structures.api.domain.idl.decorators.MultiTenancyType;
import org.kinotic.structures.internal.api.hooks.DecoratorLogic;
import org.kinotic.structures.internal.api.hooks.UpsertFieldPreProcessor;
import org.kinotic.structures.internal.api.hooks.UpsertPreProcessor;
Expand All @@ -25,15 +27,15 @@
public class MapUpsertPreProcessor implements UpsertPreProcessor<Map<Object, Object>, List<Map<Object, Object>>> {

private static final Logger log = LoggerFactory.getLogger(MapUpsertPreProcessor.class);
// Map of json path to decorator logic
private final Map<String, DecoratorLogic> fieldPreProcessors;
private final Structure structure;
private final StructuresProperties structuresProperties;
private Pair<String, DecoratorLogic> idFieldPreProcessor = null;

public MapUpsertPreProcessor(Structure structure,
StructuresProperties structuresProperties,
Map<String, DecoratorLogic> fieldPreProcessors) {
this.structure = structure;
this.fieldPreProcessors = fieldPreProcessors;
this.structuresProperties = structuresProperties;

// this is a temporary solution since we only have an id field preprocessor now.
for(Map.Entry<String, DecoratorLogic> entry : fieldPreProcessors.entrySet()) {
Expand All @@ -44,6 +46,7 @@ public MapUpsertPreProcessor(Structure structure,
break;
}
}
// FIXME: validate structure Object definition on save to ensure an ID field is present and not on a nested field
if(idFieldPreProcessor == null) {
log.warn("No id field preprocessor found for structure: {}", structure);
}
Expand All @@ -55,9 +58,10 @@ public CompletableFuture<EntityHolder> process(Map<Object, Object> entity,
EntityContext context) {
try {
// ids are not allowed to be nested
// FIXME: why isn't contains(.) just checked during C3Type conversion, and not needed here?
// FIXME: once the FIXME in the constructor is resolved, this check should be unnecessary
// We do this here since there is no way to return an error to the user from the constructor
if(idFieldPreProcessor != null && !idFieldPreProcessor.getLeft().contains(".")){
return CompletableFuture.completedFuture(processIdField(entity, context));
return CompletableFuture.completedFuture(preProcessData(entity, context));
}else{
return CompletableFuture.failedFuture(new IllegalStateException("No id field found"));
}
Expand All @@ -72,11 +76,12 @@ public CompletableFuture<List<EntityHolder>> processArray(List<Map<Object, Objec
EntityContext context) {
try {
// ids are not allowed to be nested
// FIXME: why isn't contains(.) just checked during C3Type conversion, and not needed here?
// FIXME: once the FIXME in the constructor is resolved, this check should be unnecessary
// We do this here since there is no way to return an error to the user from the constructor
if(idFieldPreProcessor != null && !idFieldPreProcessor.getLeft().contains(".")){
List<EntityHolder> entityHolders = new ArrayList<>();
for(Map<Object, Object> entity : entities) {
entityHolders.add(processIdField(entity, context));
entityHolders.add(preProcessData(entity, context));
}
return CompletableFuture.completedFuture(entityHolders);
}else{
Expand All @@ -87,7 +92,7 @@ public CompletableFuture<List<EntityHolder>> processArray(List<Map<Object, Objec
}
}

private EntityHolder processIdField(Map<Object, Object> entity, EntityContext context) {
private EntityHolder preProcessData(Map<Object, Object> entity, EntityContext context) {
String fieldName = idFieldPreProcessor.getLeft();
Object fieldValue = entity.get(fieldName);
DecoratorLogic decoratorLogic = idFieldPreProcessor.getRight();
Expand All @@ -105,6 +110,18 @@ private EntityHolder processIdField(Map<Object, Object> entity, EntityContext co
// entity data gets id without tenant
entity.put(fieldName, id);

// now verify the tenant id is set properly
if(structure.getMultiTenancyType() == MultiTenancyType.SHARED){
String existingTenantId = (String) entity.get(structuresProperties.getTenantIdFieldName());

if(existingTenantId != null && !existingTenantId.equals(context.getParticipant().getTenantId())){
throw new IllegalArgumentException("Tenant Id invalid for logged in participant");

}else if(existingTenantId == null){
entity.put(structuresProperties.getTenantIdFieldName(), context.getParticipant().getTenantId());
}
}

// if this is the id we add the special _id field for elasticsearch to use
return new EntityHolder(id,
context.getParticipant().getTenantId(),
Expand Down

0 comments on commit d6a1f1f

Please sign in to comment.