Skip to content

Commit

Permalink
epic: refactors @naturalId to favor new native format in zdl.
Browse files Browse the repository at this point in the history
  • Loading branch information
ivangsa committed Dec 13, 2024
1 parent 5a7c6e6 commit 7413cf8
Show file tree
Hide file tree
Showing 16 changed files with 94 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public Map findAggregateCommandsForMethod(Map method, Options options) {
if(entity != null) {
return Map.of("templateFile", "entities-methodBody", "entity", entity);
}
return Map.of("templateFile", "entities-methodBody");
}
return Map.of("templateFile", "aggregates-commands-methodBody", "aggregatesCommandsForMethod", aggregatesCommandsForMethod);
}
Expand Down Expand Up @@ -142,19 +143,19 @@ public String naturalIdsRepoMethodCallSignature(Map entity, Options options) {

public String findById(Map method, Options options) {
var zdl = options.get("zdl");
var naturalIdEntity = JSONPath.get(method, "$.options.naturalId");
if(naturalIdEntity != null) {
var entity = (Map) JSONPath.get(zdl, "$.allEntitiesAndEnums." + naturalIdEntity);
var hasNaturalId = JSONPath.get(method, "$.naturalId", false);
if(hasNaturalId) {
var entity = (Map) JSONPath.get(zdl, "$.allEntitiesAndEnums." + method.get("entity"));
return ZDLJavaSignatureUtils.naturalIdsRepoMethodCallSignature(entity);
}
return "findById(id)";
}

public String idFieldInitialization(Map method, Options options) {
var zdl = options.get("zdl");
var naturalIdEntity = JSONPath.get(method, "$.options.naturalId");
if(naturalIdEntity != null) {
var entity = (Map) JSONPath.get(zdl, "$.allEntitiesAndEnums." + naturalIdEntity);
var hasNaturalId = JSONPath.get(method, "$.naturalId", false);
if(hasNaturalId) {
var entity = (Map) JSONPath.get(zdl, "$.allEntitiesAndEnums." + method.get("entity"));
List<Map> fields = ZDLFindUtils.naturalIdFields(entity);
return fields.stream().map(field -> String.format("var %s = %s;", field.get("name"), ZDLJavaSignatureUtils.populateField(field)))
.collect(Collectors.joining("\n"));
Expand All @@ -164,9 +165,9 @@ public String idFieldInitialization(Map method, Options options) {

public String idParamsCallSignature(Map method, Options options) {
var zdl = options.get("zdl");
var naturalIdEntity = JSONPath.get(method, "$.options.naturalId");
if(naturalIdEntity != null) {
var entity = (Map) JSONPath.get(zdl, "$.allEntitiesAndEnums." + naturalIdEntity);
var hasNaturalId = JSONPath.get(method, "$.naturalId", false);
if(hasNaturalId) {
var entity = (Map) JSONPath.get(zdl, "$.allEntitiesAndEnums." + method.get("entity"));
var fields = ZDLFindUtils.naturalIdFields(entity);
return ZDLJavaSignatureUtils.fieldsParamsCallSignature(fields);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public {{abstractClass entity}} class {{entity.className}} {{addExtends entity}}
{{/if}}
{{~/if~}}
{{~#if field.options.transient}} @javax.persistence.Transient {{/if}}
{{~#if field.options.naturalId}} @org.hibernate.annotations.NaturalId {{/if}}
private {{{fieldType field}}} {{field.name}} {{{fieldTypeInitializer field}}};
{{/each}}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{{~assign 'entity' aggregateCommandsForMethod.entity }}
{{~assign 'hasNaturalId' (isTruthy method.options.naturalId) }}
{{~assign 'hasNaturalId' (isTruthy method.naturalId) }}
{{~assign 'notHasNaturalId' (isFalsy hasNaturalId) }}
// hasNaturalId: {{hasNaturalId}}, notHasNaturalId: {{notHasNaturalId}}
{{~#if (isCrudMethod 'create' method=method entity=entity )}}
log.debug("[CRUD] Request to save {{entity.className}}: {}", input);
var {{entity.instanceName}} = {{asInstanceName service.name}}Mapper.update(new {{entity.className}}(), {{{mapperInputCallSignature method.parameter}}});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{assign 'entity' aggregateCommandsForMethod.entity }}
{{~assign 'hasNaturalId' (isTruthy method.options.naturalId) }}
{{~assign 'hasNaturalId' (isTruthy method.naturalId) }}
{{~assign 'notHasNaturalId' (isFalsy hasNaturalId) }}
{{~#if (isCrudMethod 'create' method=method entity=entity )}}
log.debug("[CRUD] Request to save {{entity.className}}: {}", input);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ public Map<String, Object> process(Map<String, Object> contextModel) {
var paginated = JSONPath.get(method, "$.options.paginated");
var httpOption = ZDLHttpUtils.getHttpOption((Map) method);
if(httpOption != null) {
var naturalId = JSONPath.get(method, "$.options.naturalId");
var naturalIdEntity = (Map) JSONPath.get(zdl, "$.entities." + naturalId);
List<Map> naturalIdFields = ZDLFindUtils.naturalIdFields(naturalIdEntity);
var methodEntityName = JSONPath.get(method, "$.options.entity");
var methodEntity = (Map) JSONPath.get(zdl, "$.entities." + methodEntityName);
List<Map> naturalIdFields = ZDLFindUtils.naturalIdFields(methodEntity);
Map naturalIdTypes = new HashMap();
if(naturalIdFields != null) {
for (Map idField : naturalIdFields) {
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
<handlebars-java.version>4.3.1</handlebars-java.version>
<json-path.version>2.9.0</json-path.version>
<json-schema-ref-parser-jvm.version>0.8.7</json-schema-ref-parser-jvm.version>
<zdl-jvm.version>1.2.2</zdl-jvm.version>
<zdl-jvm.version>1.3.0-SNAPSHOT</zdl-jvm.version>
<graphql-java.version>19.2</graphql-java.version>
<google-java-format.version>1.7</google-java-format.version>
<palantir-java-format.version>2.38.0</palantir-java-format.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
import io.zenwave360.sdk.utils.JSONPath;
import io.zenwave360.sdk.utils.Maps;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

Expand All @@ -27,6 +25,7 @@ public Map<String, Object> process(Map<String, Object> contextModel) {

processServiceName(zdlModel);
processServiceAsyncMethods(zdlModel);
processMethodEntity(zdlModel);

contextModel = new ZDL2JDLProcessor().process(contextModel); // FIXME: why here in the middle of the process?

Expand All @@ -46,6 +45,44 @@ public Map<String, Object> process(Map<String, Object> contextModel) {
return contextModel;
}

public void processMethodEntity(Map<String, Object> zdlModel) {
var methods = JSONPath.get(zdlModel, "$.services[*].methods[*]", List.<Map>of());
for (Map method : methods) {
var serviceAggregates = JSONPath.get(zdlModel, "$.services." + method.get("serviceName") + ".aggregates", List.<String>of());
String entity = null;
String aggregate = null;
if(serviceAggregates.size() == 1) {
entity = serviceAggregates.get(0);
} else {
var returnType = JSONPath.get(method, "$.returnType");
if(serviceAggregates.contains(returnType)) {
entity = (String) returnType;
} else {
var entityForId = JSONPath.get(method, "$.options.entityForId");
if(entityForId != null) {
entity = (String) entityForId;
}
}
}

// check if entity is in fact and aggregate
var aggregateRoot = (String) JSONPath.get(zdlModel, "$.allEntitiesAndEnums." + entity + ".aggregateRoot");
if(aggregateRoot != null) {
aggregate = entity;
entity = aggregateRoot;
}

if(entity != null) {
method.put("entity", entity);
method.put("aggregate", aggregate);
} else {
if(method.get("paramId") != null) {
log.error("⚠️ We could not determine the 'entity' for the method {}. Please use `@entityForId(Entity)` annotation.", method.get("name"));
}
}
}
}

public void processServiceName(Map<String, Object> zdlModel) {
var services = JSONPath.get(zdlModel, "$.services", Map.of());
for (Map.Entry<Object, Object> service : services.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,58 +129,14 @@ public static List<String> methodEventsFlatList(Map<String, Object> method) {

public static List<Map<String, Object>> findAggregateCommandsForMethod(Map zdl, Map<String, Object> method) {
var serviceAggregateNames = JSONPath.get(zdl, "$.services." + method.get("serviceName") + ".aggregates", List.<String>of());
var methodAnnotatedAggregates = JSONPath.get(method, "$.options.aggregates", List.<String>of());
var returnType = JSONPath.get(method, "$.returnType");
if (methodAnnotatedAggregates.isEmpty()) {
String aggregateName = null;
String entityName = null;
String crudMethod = null;
String commandName = null;
if(serviceAggregateNames.size() == 1) {
aggregateName = serviceAggregateNames.get(0);
entityName = JSONPath.get(zdl, "$.allEntitiesAndEnums." + aggregateName + ".aggregateRoot");
if (entityName == null) {
// if entityName is null we need to swap entityName and aggregateName b/c the 'aggregateName' is actually just an entity
entityName = aggregateName;
aggregateName = null;
}
commandName = findAggregateCommand(zdl, method, aggregateName);
if (commandName == null) {
crudMethod = findCrudMethod(zdl, method, entityName);
if (crudMethod != null) {
aggregateName = null;
}
}
} else {
for (String serviceAggregate : serviceAggregateNames) {
aggregateName = serviceAggregate;
entityName = JSONPath.get(zdl, "$.allEntitiesAndEnums." + serviceAggregate + ".aggregateRoot");
if (entityName == null) {
// if entityName is null we need to swap entityName and aggregateName b/c the 'aggregateName' is actually just an entity
entityName = aggregateName;
aggregateName = null;
}
if(Objects.equals(returnType, entityName) || Objects.equals(returnType, aggregateName)) {
commandName = findAggregateCommand(zdl, method, aggregateName);
if(commandName != null) {
break;
}
}
crudMethod = findCrudMethod(zdl, method, entityName);
if(crudMethod != null || Objects.equals(returnType, entityName)) {
aggregateName = null;
break;
}
}
}

if(commandName == null && Objects.equals(returnType, entityName)) {
aggregateName = null; // if we didn't find an aggregate's command, we don't want to return an aggregate
}
String aggregateName = (String) method.get("aggregate");
String entityName = (String) method.get("entity");
String commandName = findAggregateCommand(zdl, method, aggregateName);
String crudMethod = findCrudMethod(zdl, method, entityName);

return List.of(methodAggregateCommand(zdl, aggregateName, commandName, entityName, crudMethod));
}
return null;
return List.of(methodAggregateCommand(zdl, aggregateName, commandName, entityName, crudMethod));
}

private static Map<String, Object> methodAggregateCommand(Map zdl, String aggregateName, String commandName, String entityName, String crudMethod) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,18 @@ public static String methodParameterType(Map method, Map zdl, String inputDTOSuf
}

public static String fieldsParamsSignature(List<Map> fields) {
if(fields == null) {
return "";
}
return fields.stream()
.map(f -> String.format("%s %s", f.get("type"), f.get("name")))
.collect(Collectors.joining(", "));
}

public static String fieldsParamsCallSignature(List<Map> fields) {
if(fields == null) {
return "";
}
return fields.stream().map(f -> f.get("name").toString()).collect(Collectors.joining(", "));
}

Expand All @@ -52,9 +58,9 @@ public static String naturalIdsRepoMethodCallSignature(Map entity) {
public static String methodParametersSignature(String idJavaType, Map method, Map zdl, String inputDTOSuffix) {
var params = new ArrayList<String>();
if(JSONPath.get(method, "paramId") != null) {
var naturalIdEntity = JSONPath.get(method, "options.naturalId");
if (naturalIdEntity != null) {
var fields = ZDLFindUtils.naturalIdFields(JSONPath.get(zdl, "$.entities." + naturalIdEntity));
var hasNaturalId = JSONPath.get(method, "naturalId", false);
if (hasNaturalId) {
var fields = ZDLFindUtils.naturalIdFields(JSONPath.get(zdl, "$.entities." + method.get("entity")));
params.add(ZDLJavaSignatureUtils.fieldsParamsSignature(fields));
} else {
params.add(idJavaType + " id");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,11 @@ public void testProcessZDL_ProcessAsyncMethods() throws Exception {
Assertions.assertEquals(2, syncMethods.size());
}

@Test
public void testProcessZDL_EntityForId() throws Exception {
var model = loadZDL("classpath:io/zenwave360/sdk/resources/zdl/natural-ids.zdl");
var attachmentInput = JSONPath.get(model, "$.zdl.inputs.AddressInputCopy", Map.of());
}


}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
MAX_LENGTH=100
/**
* Global javadoc comment
*/

MAX_LENGTH=100
config {}

apis {
asyncapi(provider) CustomerAddressAPI {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
MAX_LENGTH=100
/**
* Global javadoc comment
*/

MAX_LENGTH=100
config {}

/**
* Customer javadoc comment
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
MAX_LENGTH=100
/**
* Global javadoc comment
*/

MAX_LENGTH=100
config {}

/**
* Customer javadoc comment
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
MAX_LENGTH=100
/**
* Global javadoc comment
*/
config {}

MAX_LENGTH=100

/**
* Customer javadoc comment
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
MAX_LENGTH=100
/**
* Global javadoc comment
*/

MAX_LENGTH=100

config {
basePackage "com.example.zenwave"
plugins {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@ entity Customer {

}

output CustomerProfile {
name String required maxlength(254)
}

@rest("/customers")
service CustomerService for (Customer) {

@get("/{customerId}/{anotherId}") @naturalId(Customer)
getCustomer(id) Customer?
@get("/{customerId}/{anotherId}")
getCustomer(@natural id) Customer?

@put("/{customerId}/{anotherId}") @naturalId(Customer)
updateCustomer(id, Customer) Customer?
@put("/{customerId}/{anotherId}")
updateCustomer(@natural id, Customer) CustomerProfile?

}

0 comments on commit 7413cf8

Please sign in to comment.