Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions datamodel/openapi/openapi-api-sample/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
<pojoConstructorVisibility>protected</pojoConstructorVisibility>
<useOneOfInterfaces>true</useOneOfInterfaces>
<enumUnknownDefaultCase>true</enumUnknownDefaultCase>
<stopAdditionalProperties>true</stopAdditionalProperties>
</additionalProperties>
</configuration>
</plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ components:
example: 123
Order:
type: object
additionalProperties: true
required:
- productId
- quantity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
import com.sap.cloud.sdk.cloudplatform.connectivity.DefaultHttpDestination;
import com.sap.cloud.sdk.datamodel.openapi.sample.model.Order;
import com.sap.cloud.sdk.datamodel.openapi.sample.model.SodaWithId;

@WireMockTest
Expand Down Expand Up @@ -48,7 +49,7 @@ void testPutPayload()
}

@Test
void testJacksonSerialization()
void testJacksonSerializeSodaWithId()
throws JsonProcessingException
{
expected = """
Expand All @@ -75,6 +76,25 @@ void testJacksonSerialization()
assertThat(new ObjectMapper().writeValueAsString(obj)).isEqualToIgnoringWhitespace(expected);
}

@Test
void testJacksonSerializeOrder()
throws JsonProcessingException
{
expected = """
{
"productId": 100,
"quantity": 5,
"totalPrice": 6.0,
"typelessProperty":null,
"nullableProperty":null,
"shoesize": 44
}
""";
final Order order = Order.create().productId(100L).quantity(5).totalPrice(6.0f);
order.setCustomField("shoesize", 44);
assertThat(new ObjectMapper().writeValueAsString(order)).isEqualToIgnoringWhitespace(expected);
Copy link
Contributor Author

@newtork newtork Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Comment)

Without the enabled feature toggle this test assertion fails:

Expecting actual:
  "{}"
to be equal to:
  "{
  "productId": 100,
  "quantity": 5,
  "totalPrice": 6.0,
  "packaging" : "bottle",
  "shoesize": 44
}

}

private void verify( String requestBody )
{
WireMock
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.sap.cloud.sdk.datamodel.openapi.generator;

import static com.sap.cloud.sdk.datamodel.openapi.generator.GeneratorCustomProperties.STOP_ADDITIONAL_PROPERTIES;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Year;
Expand All @@ -11,6 +13,7 @@

import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.config.GlobalSettings;
import org.openapitools.codegen.languages.JavaClientCodegen;
Expand All @@ -23,6 +26,7 @@

import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.parser.core.models.AuthorizationValue;
import io.swagger.v3.parser.core.models.ParseOptions;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -55,7 +59,7 @@ static ClientOptInput convertGenerationConfiguration(
setGlobalSettings(generationConfiguration);
final var inputSpecFile = inputSpec.toString();

final var config = createCodegenConfig();
final var config = createCodegenConfig(generationConfiguration);
config.setOutputDir(generationConfiguration.getOutputDirectory());
config.setLibrary(LIBRARY_NAME);
config.setApiPackage(generationConfiguration.getApiPackage());
Expand All @@ -69,7 +73,7 @@ static ClientOptInput convertGenerationConfiguration(
return clientOptInput;
}

private static JavaClientCodegen createCodegenConfig()
private static JavaClientCodegen createCodegenConfig( @Nonnull final GenerationConfiguration config )
{
return new JavaClientCodegen()
{
Expand All @@ -89,6 +93,16 @@ public OperationsMap postProcessOperationsWithModels(
}
return super.postProcessOperationsWithModels(ops, allModels);
}

@SuppressWarnings( { "rawtypes", "RedundantSuppression" } )
@Override
protected void updateModelForObject( CodegenModel m, Schema schema )
{
if( STOP_ADDITIONAL_PROPERTIES.isEnabled(config) ) {
schema.setAdditionalProperties(Boolean.FALSE);
}
super.updateModelForObject(m, schema);
}
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.sap.cloud.sdk.datamodel.openapi.generator;

import javax.annotation.Nonnull;

import com.sap.cloud.sdk.datamodel.openapi.generator.model.GenerationConfiguration;

import lombok.RequiredArgsConstructor;

/**
* Optional feature toggles, may be used internally only.
*/
@RequiredArgsConstructor
enum GeneratorCustomProperties
{
/**
* Disable additional properties in generated models. They resolve to model classes extending from HashMap,
* effectively disabling serialization. Jackson by default only serializes the map entries and will ignore all
* fields from the model class.
*/
STOP_ADDITIONAL_PROPERTIES("stopAdditionalProperties", "false");

private final String key;
private final String defaultValue;

/**
* Check if the feature is enabled.
*
* @param config
* The generation configuration.
* @return True if the feature is enabled, false otherwise.
*/
public boolean isEnabled( @Nonnull final GenerationConfiguration config )
{
final var value = getValue(config);
return !value.isEmpty() && !"false".equalsIgnoreCase(value.trim());
}

/**
* Get the value of the feature.
*
* @param config
* The generation configuration.
* @return The value of the feature.
*/
@Nonnull
public String getValue( @Nonnull final GenerationConfiguration config )
{
return config.getAdditionalProperties().getOrDefault(key, defaultValue);
}
}
Loading