Skip to content

Commit

Permalink
#271 Fix model schema generation
Browse files Browse the repository at this point in the history
  • Loading branch information
jemacineiras committed Aug 21, 2023
1 parent 24bf7d2 commit 465a685
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,8 @@ private void checkReference(
}

private void processOperation(
final SpecFile fileParameter, final FileLocation ymlParent, final Entry<String, JsonNode> entry, final JsonNode channel, final String operationId,
final JsonNode channelPayload, final Map<String, JsonNode> totalSchemas) throws IOException, TemplateException {
final SpecFile fileParameter, final FileLocation ymlParent, final Entry<String, JsonNode> entry, final JsonNode channel,
final String operationId, final JsonNode channelPayload, final Map<String, JsonNode> totalSchemas) throws IOException, TemplateException {
if (isValidOperation(fileParameter.getConsumer(), operationId, channel, SUBSCRIBE, true)) {
final var operationObject = fileParameter.getConsumer();
checkClassPackageDuplicate(operationObject.getClassNamePostfix(), operationObject.getApiPackage());
Expand All @@ -349,12 +349,12 @@ private void processOperation(
}

private boolean isValidOperation(
final OperationParameterObject operation, final String operationId, final JsonNode channel, final String channelType, final boolean excludingOperationExists) {
final OperationParameterObject operation, final String operationId, final JsonNode channel, final String channelType,
final boolean excludingOperationExists) {
final boolean result;
if (operation != null) {
final List<String> operationIds = operation.getOperationIds();
result = operationIds.contains(operationId)
|| operationIds.isEmpty() && channel.has(channelType) && excludingOperationExists;
result = operationIds.contains(operationId) || operationIds.isEmpty() && channel.has(channelType) && excludingOperationExists;
} else {
result = false;
}
Expand Down Expand Up @@ -646,7 +646,7 @@ private String processExternalAvro(final String modelPackage, final FileLocation
final String fullNamespace = fileTree.get("namespace").asText() + PACKAGE_SEPARATOR + fileTree.get("name").asText();
namespace = processModelPackage(fullNamespace, modelPackage);
} catch (final IOException e) {
e.printStackTrace();
throw new FileSystemException(e);
}
return namespace;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ private static SchemaObject buildSchemaObject(
final Map<String, JsonNode> totalSchemas, final String component, final JsonNode model,
final String prefix, final String suffix, final Collection<String> modelToBuildList, final String parentPackage) {

final var listSchema = getFields(totalSchemas, model, true, prefix, suffix, modelToBuildList);
final var listSchema = getFields(totalSchemas, model, true, prefix, suffix, modelToBuildList, parentPackage);
final var splitPackage = MapperUtil.splitName(component);
final String className = splitPackage[splitPackage.length - 1];
return SchemaObject.builder()
Expand Down Expand Up @@ -140,17 +140,17 @@ private static void getTypeImports(final HashMap<String, List<String>> listHashM
}

private static List<SchemaFieldObject> getFields(
final Map<String, JsonNode> totalSchemas, final JsonNode model, final boolean required, final String prefix,
final String suffix, final Collection<String> modelToBuildList) {
final Map<String, JsonNode> totalSchemas, final JsonNode model, final boolean required, final String prefix,
final String suffix, final Collection<String> modelToBuildList, final String parentPackage) {
final var fieldObjectArrayList = new ArrayList<SchemaFieldObject>();
schemaCombinatorType = null;
if (ApiTool.hasType(model)) {
if (OBJECT.equalsIgnoreCase(model.get(TYPE).textValue())) {
processFieldObject(totalSchemas, model, prefix, suffix, modelToBuildList, fieldObjectArrayList);
processFieldObject(totalSchemas, model, prefix, suffix, modelToBuildList, fieldObjectArrayList, parentPackage);
} else if (ARRAY.equalsIgnoreCase(model.get(TYPE).textValue())) {
fieldObjectArrayList.add(processFieldObjectList(totalSchemas, "", model, required, prefix, suffix, modelToBuildList));
fieldObjectArrayList.add(processFieldObjectList(totalSchemas, "", model, required, prefix, suffix, modelToBuildList, parentPackage));
} else if ("enum".equalsIgnoreCase(model.get(TYPE).textValue())) {
fieldObjectArrayList.add(processFieldObjectList(totalSchemas, "", model, required, prefix, suffix, modelToBuildList));
fieldObjectArrayList.add(processFieldObjectList(totalSchemas, "", model, required, prefix, suffix, modelToBuildList, parentPackage));
}
} else if (model.elements().hasNext()) {
final var fieldsIt = model.fields();
Expand All @@ -160,8 +160,8 @@ private static List<SchemaFieldObject> getFields(
}

private static void processFieldObject(
final Map<String, JsonNode> totalSchemas, final JsonNode model, final String prefix, final String suffix, final Collection<String> modelToBuildList,
final ArrayList<SchemaFieldObject> fieldObjectArrayList) {
final Map<String, JsonNode> totalSchemas, final JsonNode model, final String prefix, final String suffix, final Collection<String> modelToBuildList,
final ArrayList<SchemaFieldObject> fieldObjectArrayList, String parentPackage) {
final Set<String> requiredSet = new HashSet<>();
if (model.has("required")) {
final JsonNode arrayNode = model.get("required");
Expand All @@ -173,8 +173,7 @@ private static void processFieldObject(
final var propertiesIt = model.get(PROPERTIES).fieldNames();
while (propertiesIt.hasNext()) {
final var property = propertiesIt.next();
fieldObjectArrayList.add(
processFieldObjectList(totalSchemas, property, model.get(PROPERTIES).path(property), requiredSet.contains(property), prefix, suffix, modelToBuildList));
fieldObjectArrayList.add(processFieldObjectList(totalSchemas, property, model.get(PROPERTIES).path(property), requiredSet.contains(property), prefix, suffix, modelToBuildList, parentPackage));
if (model.get(PROPERTIES).path(property).has(REF)) {
modelToBuildList.add(MapperUtil.getLongRefClass(model.get(PROPERTIES).path(property)));
}
Expand Down Expand Up @@ -246,27 +245,33 @@ private static SchemaFieldObject solveElement(
if (element.has(REF)) {
final String schemaName = MapperUtil.getLongRefClass(element);
final var schemaToProcess = totalSchemas.get(schemaName.toUpperCase());
result = processFieldObjectList(totalSchemas, schemaName, schemaToProcess, required, prefix, suffix, modelToBuildList);
result = processFieldObjectList(totalSchemas, schemaName, schemaToProcess, required, prefix, suffix, modelToBuildList, null);
result.setRequired(false);
} else {
result = processFieldObjectList(totalSchemas, "", element, required, prefix, suffix, modelToBuildList);
result = processFieldObjectList(totalSchemas, "", element, required, prefix, suffix, modelToBuildList, null);
}
return result;
}

private static SchemaFieldObject processFieldObjectList(
final Map<String, JsonNode> totalSchemas, final String propertyName, final JsonNode schema, final boolean required, final String prefix, final String suffix,
final Collection<String> modelToBuildList) {
final Map<String, JsonNode> totalSchemas, final String propertyName, final JsonNode schema, final boolean required,
final String prefix, final String suffix, final Collection<String> modelToBuildList, final String modelPackage) {
final SchemaFieldObject fieldObject;
final var name = schema.has("name") ? schema.get("name").textValue() : propertyName;
if (schema.has("type")) {
final var type = schema.get("type").textValue();
if (OBJECT.equalsIgnoreCase(type)) {
fieldObject = SchemaFieldObject.builder().restrictions(new SchemaFieldObjectProperties()).baseName(name).dataType(MapperUtil.getSimpleType(schema, prefix, suffix)).build();
fieldObject =
SchemaFieldObject
.builder()
.restrictions(new SchemaFieldObjectProperties())
.baseName(name)
.dataType(MapperUtil.getSimpleType(schema, prefix, suffix))
.build();
setFieldType(fieldObject, schema, required, prefix, suffix);
if (StringUtils.isNotEmpty(propertyName) && !totalSchemas.containsKey(propertyName)) {
totalSchemas.put(propertyName.toUpperCase(), schema);
modelToBuildList.add(propertyName);
totalSchemas.put(createKey(modelPackage, propertyName.toUpperCase(), "/"), schema);
modelToBuildList.add(createKey(modelPackage, propertyName.toUpperCase(), "."));
}
} else if (schema.has("items")) {
final var items = schema.get("items");
Expand Down Expand Up @@ -321,6 +326,10 @@ private static SchemaFieldObject processFieldObjectList(
return fieldObject;
}

private static String createKey(final String modelPackage, final String className, final String separator) {
return Objects.nonNull(modelPackage) ? modelPackage.toUpperCase() + separator + className : className;
}

private static void handleItems(final JsonNode schema, final Collection<String> modelToBuildList, final SchemaFieldObject fieldObject, final boolean required,
final JsonNode items) {
if (items.has("$ref")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,13 @@ public class AsyncApiGeneratorFixtures {
.filePath("src/test/resources/asyncapigenerator/testNestedObjectIssue/event-api.yml")
.consumer(OperationParameterObject.builder()
.modelNameSuffix("")
.apiPackage("com.sngular.scsplugin.nestedobject")
.apiPackage("com.sngular.scsplugin.nestedobject.consumer")
.modelPackage("com.sngular.scsplugin.nestedobject.model")
.useLombokModelAnnotation(true)
.build())
.supplier(OperationParameterObject.builder()
.modelNameSuffix("")
.apiPackage("com.sngular.scsplugin.nestedobject.producer")
.modelPackage("com.sngular.scsplugin.nestedobject.model")
.useLombokModelAnnotation(true)
.build())
Expand Down Expand Up @@ -332,59 +338,7 @@ static Function<Path, Boolean> validateTestFileGeneration() {
customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOMVALIDATOR_FOLDER);
}

static Function<Path, Boolean> validateTestFileGenerationNoConf() {
final String DEFAULT_CONSUMER_FOLDER = "generated/com/sngular/apigenerator/asyncapi";

final String DEFAULT_PRODUCER_FOLDER = "generated/com/sngular/apigenerator/asyncapi";

final String DEFAULT_MODEL_SCHEMA_FOLDER = "generated/com/sngular/apigenerator/asyncapi/model/schemas";

final String DEFAULT_MODEL_MESSAGE_FOLDER = "generated/com/sngular/apigenerator/asyncapi/model/messages";

final String DEFAULT_CUSTOMVALIDATOR_FOLDER = DEFAULT_MODEL_MESSAGE_FOLDER + "/customvalidator";

final String COMMON_PATH = "asyncapigenerator/testFileGenerationNoConfiguration/";

final String ASSETS_PATH = COMMON_PATH + "assets/";

final String CUSTOM_VALIDATOR_PATH = COMMON_PATH + "customvalidator/";

final String DEFAULT_EXCEPTION_API = DEFAULT_MODEL_SCHEMA_FOLDER + "/exception";

final List<String> expectedConsumerFiles = List.of(
ASSETS_PATH + "IPublishOperation.java",
ASSETS_PATH + "ISubscribeOperation.java",
ASSETS_PATH + "Producer.java",
ASSETS_PATH + "TestClassName.java");

final List<String> expectedModelSchemaFiles = List.of(
ASSETS_PATH + "CreateOrder.java",
ASSETS_PATH + "Order.java",
ASSETS_PATH + "OrderLine.java",
ASSETS_PATH + "OrderProduct.java",
ASSETS_PATH + "Waiter.java"
);

final List<String> expectedValidatorFiles = List.of(
CUSTOM_VALIDATOR_PATH + "NotNull.java",
CUSTOM_VALIDATOR_PATH + "NotNullValidator.java"
);

final List<String> expectedModelMessageFiles = List.of(
ASSETS_PATH + "OrderCreated.java"
);

final List<String> expectedExceptionFiles = List.of(
ASSETS_PATH + "ModelClassException.java");

return (path) -> commonTest(path, expectedConsumerFiles, Collections.emptyList(), DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER,
expectedExceptionFiles, DEFAULT_EXCEPTION_API) &&
modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER) &&
modelTest(path, expectedModelMessageFiles, DEFAULT_MODEL_MESSAGE_FOLDER) &&
customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOMVALIDATOR_FOLDER);
}

static Function<Path, Boolean> validateTestIssueGeneration() {
static Function<Path, Boolean> validateTestIssueGeneration() {
final String DEFAULT_CONSUMER_FOLDER = "generated/com/sngular/scsplugin/issuegeneration/model/event/consumer";

final String DEFAULT_PRODUCER_FOLDER = "generated/com/sngular/scsplugin/issuegeneration/model/event/producer";
Expand Down

0 comments on commit 465a685

Please sign in to comment.