Skip to content
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

C client generator improvements to support petstore #5837

Merged
merged 3 commits into from
Apr 7, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,12 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("apiClient.c.mustache", "src", "apiClient.c"));
supportingFiles.add(new SupportingFile("apiKey.c.mustache", "src", "apiKey.c"));
supportingFiles.add(new SupportingFile("list.c.mustache", "src", "list.c"));
supportingFiles.add(new SupportingFile("binary.c.mustache", "src", "binary.c"));
// include folder
supportingFiles.add(new SupportingFile("apiClient.h.mustache", "include", "apiClient.h"));
supportingFiles.add(new SupportingFile("keyValuePair.h.mustache", "include", "keyValuePair.h"));
supportingFiles.add(new SupportingFile("list.h.mustache", "include", "list.h"));
supportingFiles.add(new SupportingFile("binary.h.mustache", "include", "binary.h"));
// external folder
supportingFiles.add(new SupportingFile("cJSON.licence.mustache", "external", "cJSON.licence"));
supportingFiles.add(new SupportingFile("cJSON.c.mustache", "external", "cJSON.c"));
Expand Down Expand Up @@ -377,14 +379,14 @@ public String toExampleValue(Schema schema) {
example = "\"2013-10-20T19:20:30+01:00\"";
return example;
} else if (ModelUtils.isBinarySchema(schema)) {
example = "bytes(b'blah')";
example = "instantiate_binary_t(\"blah\", 5)";
return example;
} else if (ModelUtils.isByteArraySchema(schema)) {
example = "YQ==";
} else if (ModelUtils.isStringSchema(schema)) {
// a BigDecimal:
if ("Number".equalsIgnoreCase(schema.getFormat())) {return "1";}
if (StringUtils.isNotBlank(schema.getPattern())) return "'a'"; // I cheat here, since it would be too complicated to generate a string from a regexp
if (StringUtils.isNotBlank(schema.getPattern())) return "\"a\""; // I cheat here, since it would be too complicated to generate a string from a regexp
int len = 0;
if (null != schema.getMinLength()) len = schema.getMinLength().intValue();
if (len < 1) len = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ set(SRCS
src/list.c
src/apiKey.c
src/apiClient.c
src/binary.c
external/cJSON.c
model/object.c
{{#models}}
Expand All @@ -42,6 +43,7 @@ set(SRCS
set(HDRS
include/apiClient.h
include/list.h
include/binary.h
include/keyValuePair.h
external/cJSON.h
model/object.h
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../include/list.h"
#include "../external/cJSON.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"
{{#imports}}{{{import}}}
{{/imports}}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apiClient_t *apiClient_create() {
apiClient->accessToken = NULL;
{{/isOAuth}}
{{#isApiKey}}
apiClient->apiKeys = NULL;
apiClient->apiKeys_{{name}} = NULL;
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
Expand All @@ -39,7 +39,7 @@ apiClient_t *apiClient_create_with_base_path(const char *basePath
{{#hasAuthMethods}}
{{#authMethods}}
{{#isApiKey}}
, list_t *apiKeys
, list_t *apiKeys_{{name}}
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
Expand Down Expand Up @@ -70,16 +70,16 @@ apiClient_t *apiClient_create_with_base_path(const char *basePath
apiClient->accessToken = NULL;
{{/isOAuth}}
{{#isApiKey}}
if(apiKeys!= NULL) {
apiClient->apiKeys = list_create();
if(apiKeys_{{name}}!= NULL) {
apiClient->apiKeys_{{name}} = list_create();
listEntry_t *listEntry = NULL;
list_ForEach(listEntry, apiKeys) {
list_ForEach(listEntry, apiKeys_{{name}}) {
keyValuePair_t *pair = listEntry->data;
keyValuePair_t *pairDup = keyValuePair_create(strdup(pair->key), strdup(pair->value));
list_addElement(apiClient->apiKeys, pairDup);
list_addElement(apiClient->apiKeys_{{name}}, pairDup);
}
}else{
apiClient->apiKeys = NULL;
apiClient->apiKeys_{{name}} = NULL;
}
{{/isApiKey}}
{{/authMethods}}
Expand Down Expand Up @@ -108,9 +108,9 @@ void apiClient_free(apiClient_t *apiClient) {
}
{{/isOAuth}}
{{#isApiKey}}
if(apiClient->apiKeys) {
if(apiClient->apiKeys_{{name}}) {
listEntry_t *listEntry = NULL;
list_ForEach(listEntry, apiClient->apiKeys) {
list_ForEach(listEntry, apiClient->apiKeys_{{name}}) {
keyValuePair_t *pair = listEntry->data;
if(pair->key){
free(pair->key);
Expand All @@ -120,7 +120,7 @@ void apiClient_free(apiClient_t *apiClient) {
}
keyValuePair_free(pair);
}
list_free(apiClient->apiKeys);
list_free(apiClient->apiKeys_{{name}});
}
{{/isApiKey}}
{{/authMethods}}
Expand Down Expand Up @@ -440,9 +440,9 @@ void apiClient_invoke(apiClient_t *apiClient,
{{#authMethods}}
{{#isApiKey}}
// this would only be generated for apiKey authentication
if (apiClient->apiKeys != NULL)
if (apiClient->apiKeys_{{name}} != NULL)
{
list_ForEach(listEntry, apiClient->apiKeys) {
list_ForEach(listEntry, apiClient->apiKeys_{{name}}) {
keyValuePair_t *apiKey = listEntry->data;
if((apiKey->key != NULL) &&
(apiKey->value != NULL) )
Expand Down Expand Up @@ -632,7 +632,12 @@ char *base64encode (const void *b64_encode_this, int encode_this_many_bytes){
BUF_MEM_grow(mem_bio_mem_ptr, (*mem_bio_mem_ptr).length + 1); //Makes space for end null.
(*mem_bio_mem_ptr).data[(*mem_bio_mem_ptr).length] = '\0'; //Adds null-terminator to tail.
return (*mem_bio_mem_ptr).data; //Returns base-64 encoded data. (See: "buf_mem_st" struct).
#endif
#else // OPENSSL
char* ret = malloc(encode_this_many_bytes);
memcpy(ret, b64_encode_this, encode_this_many_bytes-1);
ret[encode_this_many_bytes] = 0;
return ret;
#endif // OPENSSL
}
Copy link
Contributor

@ityuhui ityuhui Apr 6, 2020

Choose a reason for hiding this comment

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

Why this fake encode/decode is needed ? If uses do not define -DOPENSSL, but use the function base64decode or base64encode , they will not get the result that they want.

I think if the users want to use the function base64decode or base64encode defined by openapi-generator/c-libcurl , they must define -DOPENSSL in CMakefile.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't get it. What if -DOPENSSL is not defined? What do you intend to happen in that case? I didn't have it defined, and the function "returned" without issuing a return statement.

Copy link
Contributor

Choose a reason for hiding this comment

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

e.g.
If uses do not define -DOPENSSL, but use the function base64encode, the returned char * is still equal to the original string, not a base64 encoded string.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought that was idea, and that's the code I implemented. The original code did nothing (not even return a buffer).

Copy link
Contributor

@ityuhui ityuhui Apr 6, 2020

Choose a reason for hiding this comment

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

Yes. I know.
So I suggest adding a warning message here if this code is needed:
e.g.

#else // OPENSSL
    fprintf(stderr, "The data will not be decoded. If you want to use this function, please define \"-DOPENSSL\" when building.\n");
    char* ret = malloc(decode_this_many_bytes);
    memcpy(ret, b64_decode_this, decode_this_many_bytes-1);
    ret[decode_this_many_bytes] = 0;
   *decoded_bytes = decode_this_many_bytes;
    return ret;
#endif // OPENSSL

Copy link
Contributor

@zhemant zhemant Apr 6, 2020

Choose a reason for hiding this comment

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

I would suggest returning NULL so the whole API call exits with an error. this is because we use strlen to get the length of the data when we add data to curl handle. This will break if the data has binary(may include null termination). So for a safer side, I would suggest to return NULL or mandate OpenSSL installation as a prerequisite.

Also if the server is expecting a base64 encoded string then we cannot send unencoded data.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What if I don't have OpenSSL, and I just want to generate unencrypted APIs?

Copy link
Contributor

Choose a reason for hiding this comment

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

If you don't have OpenSSL then you cannot send or receive binary data.

Also, I didn't get what you mean by unencrypted API? Because OpenSSL is used only for encoding binary data. It is not used for encryption.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I updated also CMakeLists.txt, but I am not an expert on cmake.


char *base64decode (const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes){
Expand All @@ -651,5 +656,11 @@ char *base64decode (const void *b64_decode_this, int decode_this_many_bytes, int
BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one).
*decoded_bytes = decoded_byte_index;
return base64_decoded; //Returns base-64 decoded data with trailing null terminator.
#endif
#else // OPENSSL
char* ret = malloc(decode_this_many_bytes);
memcpy(ret, b64_decode_this, decode_this_many_bytes-1);
ret[decode_this_many_bytes] = 0;
*decoded_bytes = decode_this_many_bytes;
return ret;
#endif // OPENSSL
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <stdint.h>
#include "../include/list.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"

typedef struct sslConfig_t {
char *clientCertFile; /* client certificate */
Expand All @@ -32,26 +33,20 @@ typedef struct apiClient_t {
char *accessToken;
{{/isOAuth}}
{{#isApiKey}}
list_t *apiKeys;
list_t *apiKeys_{{name}};
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
} apiClient_t;

typedef struct binary_t
{
uint8_t* data;
unsigned int len;
} binary_t;

apiClient_t* apiClient_create();

apiClient_t* apiClient_create_with_base_path(const char *basePath
, sslConfig_t *sslConfig
{{#hasAuthMethods}}
{{#authMethods}}
{{#isApiKey}}
, list_t *apiKeys
, list_t *apiKeys_{{name}}
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
Expand All @@ -69,6 +64,6 @@ char *strReplace(char *orig, char *rep, char *with);

char *base64encode(const void *b64_encode_this, int encode_this_many_bytes);

char *base64decode(const void *b64_decode_this, int decode_this_many_bytes);
char *base64decode(const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes);

#endif // INCLUDE_API_CLIENT_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <stdlib.h>
#include <string.h>
#include "../include/binary.h"

binary_t* instantiate_binary_t(char* data, int len) {
binary_t* ret = malloc(sizeof(struct binary_t));
ret->len=len;
ret->data = malloc(len);
memcpy(ret->data, data, len);
return ret;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef INCLUDE_BINARY_H
#define INCLUDE_BINARY_H

#include <stdint.h>

typedef struct binary_t
{
uint8_t* data;
unsigned int len;
} binary_t;

binary_t* instantiate_binary_t(char* data, int len);

#endif // INCLUDE_BINARY_H
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ fail:
}
{{/isByteArray}}
{{#isBinary}}
binary_t* decoded_str_{{{name}}};
binary_t* decoded_str_{{{name}}} = malloc(sizeof(struct binary_t));
{{^required}}if ({{{name}}}) { {{/required}}
if(!cJSON_IsString({{{name}}}))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
#include "../external/cJSON.h"
#include "../include/list.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"

char *base64encode(const void *b64_encode_this, int encode_this_many_bytes);

char *base64decode(const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes);

Copy link
Contributor

@ityuhui ityuhui Apr 6, 2020

Choose a reason for hiding this comment

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

The two functions base64encode or base64decode are declarated in apiClient.h
So why are they needed here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because I don't #include apiClient.h everywhere. I am actually considering to move base64* to binary.h / binary.c

Copy link
Contributor

@ityuhui ityuhui Apr 6, 2020

Choose a reason for hiding this comment

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

OK. I got it.

But users may want to use these 2 functions , but they do not want to include "binary.h"
So I suggest keeping the definition and decalration of the base64* functions in apiClient.h|c, but add the declarations to binary.h

Moving to binary.h/binary.c is also acceptable for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

Copy link
Contributor

Choose a reason for hiding this comment

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

Moving to binary.h/binary.c is also acceptable for me.

Copy link
Contributor

Choose a reason for hiding this comment

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

@michelealbano you dont need to include apiClient.h any where. You just need to import the main api's api.h this will import all the models required and supporting files for that API

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thinking about it, I will move them to binary.h/binary.c. I #include "../include/binary.h" in apiClient.h, thus the functions are available to whoever includes apiClient.h.

typedef struct {{classname}}_t {{classname}}_t;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "../external/cJSON.h"
#include "../include/list.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"


typedef struct object_t {
Expand Down
2 changes: 1 addition & 1 deletion samples/client/petstore/c/.openapi-generator/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.3.0-SNAPSHOT
4.3.1-SNAPSHOT
1 change: 1 addition & 0 deletions samples/client/petstore/c/api/PetAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../include/list.h"
#include "../external/cJSON.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"
#include "../model/api_response.h"
#include "../model/pet.h"

Expand Down
1 change: 1 addition & 0 deletions samples/client/petstore/c/api/StoreAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../include/list.h"
#include "../external/cJSON.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"
#include "../model/order.h"


Expand Down
1 change: 1 addition & 0 deletions samples/client/petstore/c/api/UserAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../include/list.h"
#include "../external/cJSON.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"
#include "../model/user.h"


Expand Down
13 changes: 4 additions & 9 deletions samples/client/petstore/c/include/apiClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <stdint.h>
#include "../include/list.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"

typedef struct sslConfig_t {
char *clientCertFile; /* client certificate */
Expand All @@ -22,21 +23,15 @@ typedef struct apiClient_t {
sslConfig_t *sslConfig;
void *dataReceived;
long response_code;
list_t *apiKeys;
list_t *apiKeys_api_key;
char *accessToken;
} apiClient_t;

typedef struct binary_t
{
uint8_t* data;
unsigned int len;
} binary_t;

apiClient_t* apiClient_create();

apiClient_t* apiClient_create_with_base_path(const char *basePath
, sslConfig_t *sslConfig
, list_t *apiKeys
, list_t *apiKeys_api_key
);

void apiClient_free(apiClient_t *apiClient);
Expand All @@ -51,6 +46,6 @@ char *strReplace(char *orig, char *rep, char *with);

char *base64encode(const void *b64_encode_this, int encode_this_many_bytes);

char *base64decode(const void *b64_decode_this, int decode_this_many_bytes);
char *base64decode(const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes);

#endif // INCLUDE_API_CLIENT_H
14 changes: 14 additions & 0 deletions samples/client/petstore/c/include/binary.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef INCLUDE_BINARY_H
#define INCLUDE_BINARY_H

#include <stdint.h>

typedef struct binary_t
{
uint8_t* data;
unsigned int len;
} binary_t;

binary_t* instantiate_binary_t(char* data, int len);

#endif // INCLUDE_BINARY_H
5 changes: 5 additions & 0 deletions samples/client/petstore/c/model/api_response.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
#include "../external/cJSON.h"
#include "../include/list.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"

char *base64encode(const void *b64_encode_this, int encode_this_many_bytes);

char *base64decode(const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes);

typedef struct api_response_t api_response_t;

Expand Down
5 changes: 5 additions & 0 deletions samples/client/petstore/c/model/category.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
#include "../external/cJSON.h"
#include "../include/list.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"

char *base64encode(const void *b64_encode_this, int encode_this_many_bytes);

char *base64decode(const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes);

typedef struct category_t category_t;

Expand Down
1 change: 1 addition & 0 deletions samples/client/petstore/c/model/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "../external/cJSON.h"
#include "../include/list.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"


typedef struct object_t {
Expand Down
5 changes: 5 additions & 0 deletions samples/client/petstore/c/model/order.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
#include "../external/cJSON.h"
#include "../include/list.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"

char *base64encode(const void *b64_encode_this, int encode_this_many_bytes);

char *base64decode(const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes);

typedef struct order_t order_t;

Expand Down
5 changes: 5 additions & 0 deletions samples/client/petstore/c/model/pet.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
#include "../external/cJSON.h"
#include "../include/list.h"
#include "../include/keyValuePair.h"
#include "../include/binary.h"

char *base64encode(const void *b64_encode_this, int encode_this_many_bytes);

char *base64decode(const void *b64_decode_this, int decode_this_many_bytes, int *decoded_bytes);

typedef struct pet_t pet_t;

Expand Down
Loading