-
Notifications
You must be signed in to change notification settings - Fork 8
feat(go): patch iaas/AreaID after generation to fix oneOf regex issue #277
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,11 @@ | |
|
|
||
| import org.openapitools.codegen.CodegenParameter; | ||
|
|
||
| import java.io.File; | ||
| import java.nio.file.Files; | ||
| import java.nio.file.StandardOpenOption; | ||
| import java.security.MessageDigest; | ||
| import java.util.Arrays; | ||
| import java.util.Set; | ||
| import io.swagger.v3.oas.models.media.Schema; | ||
| import io.swagger.v3.oas.models.parameters.Parameter; | ||
|
|
@@ -68,4 +73,197 @@ private boolean isRegionField(String name) { | |
| } | ||
| return name.equalsIgnoreCase("region") || name.equalsIgnoreCase("regionId"); | ||
| } | ||
| private final byte[] IAAS_AREA_ID_HASH = {-73, 66, 84, 86, -60, 99, 59, 46, -116, 10, 97, -23, -85, 59, 87, -98}; | ||
| private final String IAAS_AREA_ID_PATCHED = """ | ||
| /* | ||
| STACKIT IaaS API | ||
|
|
||
| This API allows you to create and modify IaaS resources. | ||
|
|
||
| API version: 2 | ||
| Contact: stackit-iaas@mail.schwarz | ||
| */ | ||
|
|
||
| // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. | ||
|
|
||
| package v2api | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "fmt" | ||
| "regexp" | ||
| ) | ||
|
|
||
| // AreaId - The identifier (ID) of an area. | ||
| type AreaId struct { | ||
| StaticAreaID *StaticAreaID | ||
| String *string | ||
| } | ||
|
|
||
| // StaticAreaIDAsAreaId is a convenience function that returns StaticAreaID wrapped in AreaId | ||
| func StaticAreaIDAsAreaId(v *StaticAreaID) AreaId { | ||
| return AreaId{ | ||
| StaticAreaID: v, | ||
| } | ||
| } | ||
|
|
||
| // stringAsAreaId is a convenience function that returns string wrapped in AreaId | ||
| func StringAsAreaId(v *string) AreaId { | ||
| return AreaId{ | ||
| String: v, | ||
| } | ||
| } | ||
|
|
||
| // Unmarshal JSON data into one of the pointers in the struct | ||
| func (dst *AreaId) UnmarshalJSON(data []byte) error { | ||
| var err error | ||
| match := 0 | ||
| // try to unmarshal data into StaticAreaID | ||
| err = json.Unmarshal(data, &dst.StaticAreaID) | ||
| if err == nil { | ||
| jsonStaticAreaID, _ := json.Marshal(dst.StaticAreaID) | ||
| if string(jsonStaticAreaID) == "{}" { // empty struct | ||
| dst.StaticAreaID = nil | ||
| } else { | ||
| match++ | ||
| } | ||
| } else { | ||
| dst.StaticAreaID = nil | ||
| } | ||
|
|
||
| // try to unmarshal data into String | ||
| err = json.Unmarshal(data, &dst.String) | ||
| if err == nil { | ||
| jsonString, _ := json.Marshal(dst.String) | ||
| regex := `/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/` | ||
| regex = regexp.MustCompile("^\\\\/|\\\\/$").ReplaceAllString(regex, "$1") // Remove beginning slash and ending slash | ||
| regex = regexp.MustCompile("\\\\\\\\(.)").ReplaceAllString(regex, "$1") // Remove duplicate escaping char for dots | ||
| rawString := regexp.MustCompile(`^"|"$`).ReplaceAllString(*dstAreaId1.String, "$1") // Remove quotes | ||
| isMatched, _ := regexp.MatchString(regex, rawString) | ||
| if string(jsonString) != "{}" && isMatched { // empty struct | ||
| dst.String = nil | ||
| } else { | ||
| match++ | ||
| } | ||
| } else { | ||
| dst.String = nil | ||
| } | ||
|
|
||
| if match > 1 { // more than 1 match | ||
| // reset to nil | ||
| dst.StaticAreaID = nil | ||
| dst.String = nil | ||
|
|
||
| return fmt.Errorf("data matches more than one schema in oneOf(AreaId)") | ||
| } else if match == 1 { | ||
| return nil // exactly one match | ||
| } else { // no match | ||
| return fmt.Errorf("data failed to match schemas in oneOf(AreaId)") | ||
| } | ||
| } | ||
|
|
||
| // Marshal data from the first non-nil pointers in the struct to JSON | ||
| func (src AreaId) MarshalJSON() ([]byte, error) { | ||
| if src.StaticAreaID != nil { | ||
| return json.Marshal(&src.StaticAreaID) | ||
| } | ||
|
|
||
| if src.String != nil { | ||
| return json.Marshal(&src.String) | ||
| } | ||
|
|
||
| return nil, nil // no data in oneOf schemas | ||
| } | ||
|
|
||
| // Get the actual instance | ||
| func (obj *AreaId) GetActualInstance() interface{} { | ||
| if obj == nil { | ||
| return nil | ||
| } | ||
| if obj.StaticAreaID != nil { | ||
| return obj.StaticAreaID | ||
| } | ||
|
|
||
| if obj.String != nil { | ||
| return obj.String | ||
| } | ||
|
|
||
| // all schemas are nil | ||
| return nil | ||
| } | ||
|
|
||
| // Get the actual instance value | ||
| func (obj AreaId) GetActualInstanceValue() interface{} { | ||
| if obj.StaticAreaID != nil { | ||
| return *obj.StaticAreaID | ||
| } | ||
|
|
||
| if obj.String != nil { | ||
| return *obj.String | ||
| } | ||
|
|
||
| // all schemas are nil | ||
| return nil | ||
| } | ||
|
|
||
| type NullableAreaId struct { | ||
| value *AreaId | ||
| isSet bool | ||
| } | ||
|
|
||
| func (v NullableAreaId) Get() *AreaId { | ||
| return v.value | ||
| } | ||
|
|
||
| func (v *NullableAreaId) Set(val *AreaId) { | ||
| v.value = val | ||
| v.isSet = true | ||
| } | ||
|
|
||
| func (v NullableAreaId) IsSet() bool { | ||
| return v.isSet | ||
| } | ||
|
|
||
| func (v *NullableAreaId) Unset() { | ||
| v.value = nil | ||
| v.isSet = false | ||
| } | ||
|
|
||
| func NewNullableAreaId(val *AreaId) *NullableAreaId { | ||
| return &NullableAreaId{value: val, isSet: true} | ||
| } | ||
|
|
||
| func (v NullableAreaId) MarshalJSON() ([]byte, error) { | ||
| return json.Marshal(v.value) | ||
| } | ||
|
|
||
| func (v *NullableAreaId) UnmarshalJSON(src []byte) error { | ||
| v.isSet = true | ||
| return json.Unmarshal(src, &v.value) | ||
| } | ||
| """; | ||
|
|
||
| @Override | ||
| public void postProcessFile(File file, String fileType) { | ||
| if (file.getAbsolutePath().endsWith("iaas/v2api/model_area_id.go")) { | ||
| try { | ||
| var content = Files.readAllBytes(file.toPath()); | ||
| var digest = MessageDigest.getInstance("MD5"); | ||
| var hash = digest.digest(content); | ||
| if (Arrays.equals(hash, IAAS_AREA_ID_HASH)) { | ||
| Files.writeString(file.toPath(), IAAS_AREA_ID_PATCHED, StandardOpenOption.TRUNCATE_EXISTING); | ||
| } else { | ||
| throw new IllegalStateException( | ||
| "expected iaas/v2api/model_area_id.go to hash to " + | ||
| Arrays.toString(IAAS_AREA_ID_HASH) + " but got " + Arrays.toString(hash) + | ||
| "\nedit CustomRegionGenerator.java in the sdk-generator and update IAAS_AREA_ID_HASH" + | ||
| "to accept this change" | ||
| ); | ||
| } | ||
|
Comment on lines
+248
to
+262
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This fixes it only for the v2api, but we have the same issue in v1, v2alpha and v2beta. I think it would be nice, if we have the option to apply the same fix for multiple versions of an service.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Introducing a method |
||
| } catch (Exception e) { | ||
| throw new RuntimeException(e); | ||
| } | ||
| } | ||
| super.postProcessFile(file, fileType); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two replaces were in the previous implementation, because the openapi generator didn't pass the regex 1:1 from the api schema. Instead it modified the regex a bit and we had to revert these changes. With this new approach we can copy the regex directly from the api spec and don't need this part anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice hint thanks, currently this part also generates invalid go code. I've probably made an error when escaping
\.I'd address this when we've decided on the general approach.