From a168b9e862d2dc7b90eba7138a26de5900afd028 Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 5 Aug 2026 13:48:22 +0200 Subject: [PATCH] Fix Brevo inconsitencies due to invalid openapi specs Fixes #243 Fixes #206 --- CHANGELOG.md | 5 +- .../xdev/brevo/model/CreateDomainModel.java | 8 +- .../java/software/xdev/brevo/model/Order.java | 25 +++-- .../xdev/brevo/model/OrderMetaInfoValue.java | 104 ----------------- .../brevo/model/PostContactInfoContacts.java | 59 ++++++++-- .../model/PostContactInfoContactsFailure.java | 105 ------------------ .../model/PostContactInfoContactsSuccess.java | 105 ------------------ openapi/INFO.md | 7 +- openapi/openapi.yml | 47 +++----- 9 files changed, 88 insertions(+), 377 deletions(-) delete mode 100644 brevo-java-client/src/generated/java/software/xdev/brevo/model/OrderMetaInfoValue.java delete mode 100644 brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContactsFailure.java delete mode 100644 brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContactsSuccess.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 478ae25c..86eab62d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 1.2.1 +* Fixed problems with Brevo API #206 #243 + # 1.2.0 * Updated to Jackson v3 * Updated dependencies @@ -7,7 +10,7 @@ # 1.1.0 * Updated generated code from Brevo's openapi.yml -* Updated references to "new" official Brevo client # +* Updated references to "new" official Brevo client * Updated dependencies # 1.0.4 diff --git a/brevo-java-client/src/generated/java/software/xdev/brevo/model/CreateDomainModel.java b/brevo-java-client/src/generated/java/software/xdev/brevo/model/CreateDomainModel.java index 9e45629c..6623fb6c 100644 --- a/brevo-java-client/src/generated/java/software/xdev/brevo/model/CreateDomainModel.java +++ b/brevo-java-client/src/generated/java/software/xdev/brevo/model/CreateDomainModel.java @@ -41,7 +41,7 @@ public class CreateDomainModel { public static final String JSON_PROPERTY_ID = "id"; @jakarta.annotation.Nonnull - private Long id; + private String id; public static final String JSON_PROPERTY_DOMAIN_NAME = "domain_name"; @jakarta.annotation.Nullable @@ -62,7 +62,7 @@ public class CreateDomainModel { public CreateDomainModel() { } - public CreateDomainModel id(@jakarta.annotation.Nonnull Long id) { + public CreateDomainModel id(@jakarta.annotation.Nonnull String id) { this.id = id; return this; @@ -76,14 +76,14 @@ public CreateDomainModel id(@jakarta.annotation.Nonnull Long id) { @JsonProperty(value = JSON_PROPERTY_ID, required = true) @JsonInclude(value = JsonInclude.Include.ALWAYS) - public Long getId() { + public String getId() { return id; } @JsonProperty(value = JSON_PROPERTY_ID, required = true) @JsonInclude(value = JsonInclude.Include.ALWAYS) - public void setId(@jakarta.annotation.Nonnull Long id) { + public void setId(@jakarta.annotation.Nonnull String id) { this.id = id; } diff --git a/brevo-java-client/src/generated/java/software/xdev/brevo/model/Order.java b/brevo-java-client/src/generated/java/software/xdev/brevo/model/Order.java index d72a4bfb..62ac17f8 100644 --- a/brevo-java-client/src/generated/java/software/xdev/brevo/model/Order.java +++ b/brevo-java-client/src/generated/java/software/xdev/brevo/model/Order.java @@ -28,7 +28,6 @@ import java.util.Map; import software.xdev.brevo.model.OrderBilling; import software.xdev.brevo.model.OrderIdentifiers; -import software.xdev.brevo.model.OrderMetaInfoValue; import software.xdev.brevo.model.OrderProductsInner; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.annotation.JsonTypeName; @@ -96,7 +95,7 @@ public class Order { public static final String JSON_PROPERTY_META_INFO = "metaInfo"; @jakarta.annotation.Nullable - private Map metaInfo = new HashMap<>(); + private Map metaInfo = new HashMap<>(); public Order() { } @@ -367,13 +366,13 @@ public void setCoupons(@jakarta.annotation.Nullable List coupons) { this.coupons = coupons; } - public Order metaInfo(@jakarta.annotation.Nullable Map metaInfo) { + public Order metaInfo(@jakarta.annotation.Nullable Map metaInfo) { this.metaInfo = metaInfo; return this; } - public Order putMetaInfoItem(String key, OrderMetaInfoValue metaInfoItem) { + public Order putMetaInfoItem(String key, Object metaInfoItem) { if (this.metaInfo == null) { this.metaInfo = new HashMap<>(); } @@ -387,16 +386,16 @@ public Order putMetaInfoItem(String key, OrderMetaInfoValue metaInfoItem) { */ @jakarta.annotation.Nullable @JsonProperty(value = JSON_PROPERTY_META_INFO, required = false) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.USE_DEFAULTS) - public Map getMetaInfo() { + public Map getMetaInfo() { return metaInfo; } @JsonProperty(value = JSON_PROPERTY_META_INFO, required = false) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setMetaInfo(@jakarta.annotation.Nullable Map metaInfo) { + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.USE_DEFAULTS) + public void setMetaInfo(@jakarta.annotation.Nullable Map metaInfo) { this.metaInfo = metaInfo; } @@ -584,9 +583,13 @@ public String toUrlQueryString(String prefix) { // add `metaInfo` to the URL query string if (getMetaInfo() != null) { for (String _key : getMetaInfo().keySet()) { - if (getMetaInfo().get(_key) != null) { - joiner.add(getMetaInfo().get(_key).toUrlQueryString(String.format(java.util.Locale.ROOT, "%smetaInfo%s%s", prefix, suffix, - "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, _key, containerSuffix)))); + try { + joiner.add(String.format(java.util.Locale.ROOT, "%smetaInfo%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, _key, containerSuffix), + getMetaInfo().get(_key), URLEncoder.encode(String.valueOf(getMetaInfo().get(_key)), "UTF-8").replaceAll("\\+", "%20"))); + } catch (UnsupportedEncodingException e) { + // Should never happen, UTF-8 is always supported + throw new RuntimeException(e); } } } diff --git a/brevo-java-client/src/generated/java/software/xdev/brevo/model/OrderMetaInfoValue.java b/brevo-java-client/src/generated/java/software/xdev/brevo/model/OrderMetaInfoValue.java deleted file mode 100644 index 8e4165b2..00000000 --- a/brevo-java-client/src/generated/java/software/xdev/brevo/model/OrderMetaInfoValue.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Brevo API - * Brevo API documentation by XDEV Software based on https://api.brevo.com/v3/swagger_definition_v3.yml - * - * The version of the OpenAPI document: 3.0.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package software.xdev.brevo.model; - -import java.util.Objects; -import java.util.Arrays; -import com.fasterxml.jackson.annotation.JsonTypeName; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.annotation.JsonTypeName; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.StringJoiner; - -/** - * OrderMetaInfoValue - */ -@JsonPropertyOrder({ -}) -@JsonTypeName("order_metaInfo_value") -public class OrderMetaInfoValue { - public OrderMetaInfoValue() { - } - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return Objects.hash(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class OrderMetaInfoValue {\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - return o == null ? "null" : o.toString().replace("\n", "\n "); - } - - /** - * Convert the instance into URL query string. - * - * @return URL query string - */ - public String toUrlQueryString() { - return toUrlQueryString(null); - } - - /** - * Convert the instance into URL query string. - * - * @param prefix prefix of the query string - * @return URL query string - */ - public String toUrlQueryString(String prefix) { - String suffix = ""; - String containerSuffix = ""; - String containerPrefix = ""; - if (prefix == null) { - // style=form, explode=true, e.g. /pet?name=cat&type=manx - prefix = ""; - } else { - // deepObject style e.g. /pet?id[name]=cat&id[type]=manx - prefix = prefix + "["; - suffix = "]"; - containerSuffix = "]"; - containerPrefix = "["; - } - - StringJoiner joiner = new StringJoiner("&"); - - return joiner.toString(); - } - -} - diff --git a/brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContacts.java b/brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContacts.java index a11f5803..7c0ee5d0 100644 --- a/brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContacts.java +++ b/brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContacts.java @@ -20,8 +20,9 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonValue; -import software.xdev.brevo.model.PostContactInfoContactsFailure; -import software.xdev.brevo.model.PostContactInfoContactsSuccess; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.annotation.JsonTypeName; import java.io.UnsupportedEncodingException; @@ -41,11 +42,11 @@ public class PostContactInfoContacts { public static final String JSON_PROPERTY_SUCCESS = "success"; @jakarta.annotation.Nullable - private PostContactInfoContactsSuccess success; + private List success = new ArrayList<>(); public static final String JSON_PROPERTY_FAILURE = "failure"; @jakarta.annotation.Nullable - private PostContactInfoContactsFailure failure; + private List failure = new ArrayList<>(); public static final String JSON_PROPERTY_TOTAL = "total"; @jakarta.annotation.Nullable @@ -58,12 +59,20 @@ public class PostContactInfoContacts { public PostContactInfoContacts() { } - public PostContactInfoContacts success(@jakarta.annotation.Nullable PostContactInfoContactsSuccess success) { + public PostContactInfoContacts success(@jakarta.annotation.Nullable List success) { this.success = success; return this; } + public PostContactInfoContacts addSuccessItem(String successItem) { + if (this.success == null) { + this.success = new ArrayList<>(); + } + this.success.add(successItem); + return this; + } + /** * Get success * @return success @@ -72,23 +81,31 @@ public PostContactInfoContacts success(@jakarta.annotation.Nullable PostContactI @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = false) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public PostContactInfoContactsSuccess getSuccess() { + public List getSuccess() { return success; } @JsonProperty(value = JSON_PROPERTY_SUCCESS, required = false) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setSuccess(@jakarta.annotation.Nullable PostContactInfoContactsSuccess success) { + public void setSuccess(@jakarta.annotation.Nullable List success) { this.success = success; } - public PostContactInfoContacts failure(@jakarta.annotation.Nullable PostContactInfoContactsFailure failure) { + public PostContactInfoContacts failure(@jakarta.annotation.Nullable List failure) { this.failure = failure; return this; } + public PostContactInfoContacts addFailureItem(String failureItem) { + if (this.failure == null) { + this.failure = new ArrayList<>(); + } + this.failure.add(failureItem); + return this; + } + /** * Get failure * @return failure @@ -97,14 +114,14 @@ public PostContactInfoContacts failure(@jakarta.annotation.Nullable PostContactI @JsonProperty(value = JSON_PROPERTY_FAILURE, required = false) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public PostContactInfoContactsFailure getFailure() { + public List getFailure() { return failure; } @JsonProperty(value = JSON_PROPERTY_FAILURE, required = false) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setFailure(@jakarta.annotation.Nullable PostContactInfoContactsFailure failure) { + public void setFailure(@jakarta.annotation.Nullable List failure) { this.failure = failure; } @@ -233,12 +250,30 @@ public String toUrlQueryString(String prefix) { // add `success` to the URL query string if (getSuccess() != null) { - joiner.add(getSuccess().toUrlQueryString(prefix + "success" + suffix)); + for (int i = 0; i < getSuccess().size(); i++) { + try { + joiner.add(String.format(java.util.Locale.ROOT, "%ssuccess%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + URLEncoder.encode(String.valueOf(getSuccess().get(i)), "UTF-8").replaceAll("\\+", "%20"))); + } catch (UnsupportedEncodingException e) { + // Should never happen, UTF-8 is always supported + throw new RuntimeException(e); + } + } } // add `failure` to the URL query string if (getFailure() != null) { - joiner.add(getFailure().toUrlQueryString(prefix + "failure" + suffix)); + for (int i = 0; i < getFailure().size(); i++) { + try { + joiner.add(String.format(java.util.Locale.ROOT, "%sfailure%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + URLEncoder.encode(String.valueOf(getFailure().get(i)), "UTF-8").replaceAll("\\+", "%20"))); + } catch (UnsupportedEncodingException e) { + // Should never happen, UTF-8 is always supported + throw new RuntimeException(e); + } + } } // add `total` to the URL query string diff --git a/brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContactsFailure.java b/brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContactsFailure.java deleted file mode 100644 index b451bd93..00000000 --- a/brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContactsFailure.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Brevo API - * Brevo API documentation by XDEV Software based on https://api.brevo.com/v3/swagger_definition_v3.yml - * - * The version of the OpenAPI document: 3.0.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package software.xdev.brevo.model; - -import java.util.Objects; -import java.util.Arrays; -import com.fasterxml.jackson.annotation.JsonTypeName; -import java.util.List; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.annotation.JsonTypeName; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.StringJoiner; - -/** - * PostContactInfoContactsFailure - */ -@JsonPropertyOrder({ -}) -@JsonTypeName("postContactInfo_contacts_failure") -public class PostContactInfoContactsFailure { - public PostContactInfoContactsFailure() { - } - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return Objects.hash(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class PostContactInfoContactsFailure {\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - return o == null ? "null" : o.toString().replace("\n", "\n "); - } - - /** - * Convert the instance into URL query string. - * - * @return URL query string - */ - public String toUrlQueryString() { - return toUrlQueryString(null); - } - - /** - * Convert the instance into URL query string. - * - * @param prefix prefix of the query string - * @return URL query string - */ - public String toUrlQueryString(String prefix) { - String suffix = ""; - String containerSuffix = ""; - String containerPrefix = ""; - if (prefix == null) { - // style=form, explode=true, e.g. /pet?name=cat&type=manx - prefix = ""; - } else { - // deepObject style e.g. /pet?id[name]=cat&id[type]=manx - prefix = prefix + "["; - suffix = "]"; - containerSuffix = "]"; - containerPrefix = "["; - } - - StringJoiner joiner = new StringJoiner("&"); - - return joiner.toString(); - } - -} - diff --git a/brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContactsSuccess.java b/brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContactsSuccess.java deleted file mode 100644 index 871b8053..00000000 --- a/brevo-java-client/src/generated/java/software/xdev/brevo/model/PostContactInfoContactsSuccess.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Brevo API - * Brevo API documentation by XDEV Software based on https://api.brevo.com/v3/swagger_definition_v3.yml - * - * The version of the OpenAPI document: 3.0.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package software.xdev.brevo.model; - -import java.util.Objects; -import java.util.Arrays; -import com.fasterxml.jackson.annotation.JsonTypeName; -import java.util.List; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.annotation.JsonTypeName; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.StringJoiner; - -/** - * PostContactInfoContactsSuccess - */ -@JsonPropertyOrder({ -}) -@JsonTypeName("postContactInfo_contacts_success") -public class PostContactInfoContactsSuccess { - public PostContactInfoContactsSuccess() { - } - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return Objects.hash(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class PostContactInfoContactsSuccess {\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - return o == null ? "null" : o.toString().replace("\n", "\n "); - } - - /** - * Convert the instance into URL query string. - * - * @return URL query string - */ - public String toUrlQueryString() { - return toUrlQueryString(null); - } - - /** - * Convert the instance into URL query string. - * - * @param prefix prefix of the query string - * @return URL query string - */ - public String toUrlQueryString(String prefix) { - String suffix = ""; - String containerSuffix = ""; - String containerPrefix = ""; - if (prefix == null) { - // style=form, explode=true, e.g. /pet?name=cat&type=manx - prefix = ""; - } else { - // deepObject style e.g. /pet?id[name]=cat&id[type]=manx - prefix = prefix + "["; - suffix = "]"; - containerSuffix = "]"; - containerPrefix = "["; - } - - StringJoiner joiner = new StringJoiner("&"); - - return joiner.toString(); - } - -} - diff --git a/openapi/INFO.md b/openapi/INFO.md index cd33749d..ea3c2d9a 100644 --- a/openapi/INFO.md +++ b/openapi/INFO.md @@ -1,12 +1,15 @@ This ``openapi.yml`` is based on the [official available one](https://api.brevo.com/v3/swagger_definition_v3.yml) with minor modifications. -Changes: +Changes to fix generation: * Replaced ```yaml additionalProperties: oneOf: ``` - with ``additionalProperties: true`` as it can't be generated correctly otherwise + with `additionalProperties: true` +* Replaced `oneOf`s in `postContactInfo` (see https://github.com/xdev-software/brevo-java-client/issues/243) +* Replaced `oneOf`s in `order->metaInfo` with `additionalProperties: true` +* Changed type of `id` (in response) in `createDomain` to `string` (see https://github.com/xdev-software/brevo-java-client/issues/206) The Java API Client can be generated using ``mvn clean compile -P openapi-generator`` inside [``brevo-java-client``](../brevo-java-client/). diff --git a/openapi/openapi.yml b/openapi/openapi.yml index a1594fc2..d988766f 100644 --- a/openapi/openapi.yml +++ b/openapi/openapi.yml @@ -19583,9 +19583,8 @@ components: type: object properties: id: - type: integer + type: string description: ID of the Domain created - format: int64 example: 5 domain_name: type: string @@ -19870,33 +19869,19 @@ components: type: object properties: success: - oneOf: - - type: array - items: - type: string - description: Email addresses which are successfully imported/removed - format: email - example: jeff32@example.com, jim56@example.com - - type: array - items: - type: integer - description: IDs which are successfully imported/removed - format: int64 - example: 1, 2 + type: array + items: + type: string + description: Email addresses or IDs which are successfully imported/removed + format: email + example: jeff32@example.com, jim56@example.com, 1, 2 failure: - oneOf: - - type: array - items: - type: string - description: Email addresses which can not be imported/removed, could be already in/out list and/or doesn't exist - format: email - example: jeff32@example.com, jim56@example.com - - type: array - items: - type: integer - description: IDs which can not be imported/removed, could be already in/out list and/or doesn't exist - format: int64 - example: 5, 6 + type: array + items: + type: string + description: Email addresses or IDs which can not be imported/removed, could be already in/out list and/or doesn't exist + format: email + example: jeff32@example.com, jim56@example.com, 5, 6 total: type: integer description: Displays the count of total number of contacts removed @@ -25414,11 +25399,7 @@ components: type: string metaInfo: type: object - additionalProperties: - oneOf: - - type: string - - type: integer - - type: boolean + additionalProperties: true description: Meta data of order to store additional detal such as custom message, customer type, source. example: { "order_source": "Website",