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++ pistache server] Support basic query handling #943

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
protected boolean isAddExternalLibs = true;
public static final String OPTIONAL_EXTERNAL_LIB = "addExternalLibs";
public static final String OPTIONAL_EXTERNAL_LIB_DESC = "Add the Possibility to fetch and compile external Libraries needed by this Framework.";
public static final String HELPERS_PACKAGE_NAME = "helpersPackage";
public static final String HELPERS_PACKAGE_NAME_DESC = "Specify the package name to be used for the helpers (e.g. org.openapitools.server.helpers).";
protected final String PREFIX = "";

protected String helpersPackage = "";
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
Expand All @@ -70,6 +72,7 @@ public CppPistacheServerCodegen() {
modelNamePrefix = PREFIX;
}

helpersPackage = "org.openapitools.server.helpers";
apiPackage = "org.openapitools.server.api";
modelPackage = "org.openapitools.server.model";

Expand All @@ -86,11 +89,14 @@ public CppPistacheServerCodegen() {

cliOptions.clear();
addSwitch(OPTIONAL_EXTERNAL_LIB, OPTIONAL_EXTERNAL_LIB_DESC, this.isAddExternalLibs);
addOption(HELPERS_PACKAGE_NAME, HELPERS_PACKAGE_NAME_DESC, this.helpersPackage);

reservedWords = new HashSet<>();

supportingFiles.add(new SupportingFile("modelbase-header.mustache", "model", modelNamePrefix + "ModelBase.h"));
supportingFiles.add(new SupportingFile("modelbase-source.mustache", "model", modelNamePrefix + "ModelBase.cpp"));
supportingFiles.add(new SupportingFile("helpers-header.mustache", "model", modelNamePrefix + "Helpers.h"));
supportingFiles.add(new SupportingFile("helpers-source.mustache", "model", modelNamePrefix + "Helpers.cpp"));
supportingFiles.add(new SupportingFile("cmake.mustache", "", "CMakeLists.txt"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));

Expand Down Expand Up @@ -123,18 +129,26 @@ public CppPistacheServerCodegen() {
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(HELPERS_PACKAGE_NAME)) {
helpersPackage = (String) additionalProperties.get(HELPERS_PACKAGE_NAME);
}
if (additionalProperties.containsKey("modelNamePrefix")) {
additionalProperties().put("prefix", modelNamePrefix);
supportingFiles.clear();
supportingFiles.add(new SupportingFile("modelbase-header.mustache", "model", modelNamePrefix + "ModelBase.h"));
supportingFiles.add(new SupportingFile("modelbase-source.mustache", "model", modelNamePrefix + "ModelBase.cpp"));
supportingFiles.add(new SupportingFile("helpers-header.mustache", "model", modelNamePrefix + "Helpers.h"));
supportingFiles.add(new SupportingFile("helpers-source.mustache", "model", modelNamePrefix + "Helpers.cpp"));
supportingFiles.add(new SupportingFile("cmake.mustache", "", "CMakeLists.txt"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}
additionalProperties.put("modelNamespaceDeclarations", modelPackage.split("\\."));
additionalProperties.put("modelNamespace", modelPackage.replaceAll("\\.", "::"));
additionalProperties.put("apiNamespaceDeclarations", apiPackage.split("\\."));
additionalProperties.put("apiNamespace", apiPackage.replaceAll("\\.", "::"));
additionalProperties.put("apiNamespace", apiPackage.replaceAll("\\.", "::"));
additionalProperties.put("helpersNamespaceDeclarations", helpersPackage.split("\\."));
additionalProperties.put("helpersNamespace", helpersPackage.replaceAll("\\.", "::"));

if (additionalProperties.containsKey(OPTIONAL_EXTERNAL_LIB)) {
setAddExternalLibs(convertPropertyToBooleanAndWriteBack(OPTIONAL_EXTERNAL_LIB));
} else {
Expand Down Expand Up @@ -236,7 +250,7 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
if (param.isPrimitiveType) {
param.dataType = "Pistache::Optional<" + param.dataType + ">";
} else {
param.dataType = "Pistache::Optional<" + param.baseType + ">";
param.dataType = "Pistache::Optional<" + param.dataType + ">";
param.baseType = "Pistache::Optional<" + param.baseType + ">";
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ using namespace {{modelNamespace}};{{/hasModelImport}}
class {{declspec}} {{classname}} {
public:
{{classname}}(Pistache::Address addr);
virtual ~{{classname}}() {};
virtual ~{{classname}}() {}
void init(size_t thr);
void start();
void shutdown();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ using namespace {{modelNamespace}};{{/hasModelImport}}
class {{classname}}Impl : public {{apiNamespace}}::{{classname}} {
public:
{{classname}}Impl(Pistache::Address addr);
~{{classname}}Impl() { };
~{{classname}}Impl() {}

{{#operation}}
{{#vendorExtensions.x-codegen-pistache-isParsingSupported}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
{{#operations}}

#include "{{classname}}.h"
#include "{{prefix}}Helpers.h"

{{#apiNamespaceDeclarations}}
namespace {{this}} {
{{/apiNamespaceDeclarations}}

using namespace {{helpersNamespace}};
{{#hasModelImport}}
using namespace {{modelNamespace}};{{/hasModelImport}}

Expand Down Expand Up @@ -62,7 +64,14 @@ void {{classname}}::{{operationIdSnakeCase}}_handler(const Pistache::Rest::Reque
{{/hasBodyParam}}{{#hasQueryParams}}
// Getting the query params
{{#queryParams}}
auto {{paramName}} = request.query().get("{{baseName}}");
auto {{paramName}}Query = request.query().get("{{baseName}}");
Pistache::Optional<{{^isContainer}}{{dataType}}{{/isContainer}}{{#isListContainer}}std::vector<{{items.baseType}}>{{/isListContainer}}> {{paramName}};
if(!{{paramName}}Query.isEmpty()){
{{^isContainer}}{{dataType}}{{/isContainer}}{{#isListContainer}}std::vector<{{items.baseType}}>{{/isListContainer}} value;
if(fromStringValue({{paramName}}Query.get(), value)){
{{paramName}} = Pistache::Some(value);
}
}
{{/queryParams}}
{{/hasQueryParams}}{{#hasHeaderParams}}
// Getting the header params
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ set(<%classnameSnakeUpperCase%>_SERVER_SOURCES
<%#operations%>
add_executable(<%classnameSnakeLowerCase%>_server
${<%classnameSnakeUpperCase%>_SERVER_SOURCES})
<%#addExternalLibs%>
add_dependencies(<%classnameSnakeLowerCase%>_server PISTACHE NLOHMANN)
<%/addExternalLibs%>
<%/operations%>
<%/apiInfo.apis%>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{{>licenseInfo}}
/*
* {{prefix}}Helpers.h
*
* This is the helper class for models and primitives
*/

#ifndef {{prefix}}Helpers_H_
#define {{prefix}}Helpers_H_

#include <ctime>
#include <string>
#include <sstream>
#include <vector>
#include <map>

{{#helpersNamespaceDeclarations}}
namespace {{this}} {
{{/helpersNamespaceDeclarations}}

std::string toStringValue(const std::string &value);
std::string toStringValue(const int32_t &value);
std::string toStringValue(const int64_t &value);
std::string toStringValue(const bool &value);
std::string toStringValue(const float &value);
std::string toStringValue(const double &value);

bool fromStringValue(const std::string &inStr, std::string &value);
bool fromStringValue(const std::string &inStr, int32_t &value);
bool fromStringValue(const std::string &inStr, int64_t &value);
bool fromStringValue(const std::string &inStr, bool &value);
bool fromStringValue(const std::string &inStr, float &value);
bool fromStringValue(const std::string &inStr, double &value);
template<typename T>
bool fromStringValue(const std::vector<std::string> &inStr, std::vector<T> &value){
try{
for(auto & item : inStr){
T itemValue;
if(fromStringValue(item, itemValue)){
value.push_back(itemValue);
}
}
}
catch(...){
return false;
}
return value.size() > 0;
}
template<typename T>
bool fromStringValue(const std::string &inStr, std::vector<T> &value, char separator = ','){
std::vector<std::string> inStrings;
std::istringstream f(inStr);
std::string s;
while (std::getline(f, s, separator)) {
inStrings.push_back(s);
}
return fromStringValue(inStrings, value);
}

{{#helpersNamespaceDeclarations}}
}
{{/helpersNamespaceDeclarations}}

#endif // {{prefix}}Helpers_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{{>licenseInfo}}
#include "{{prefix}}Helpers.h"

{{#helpersNamespaceDeclarations}}
namespace {{this}} {
{{/helpersNamespaceDeclarations}}


std::string toStringValue(const std::string &value){
return std::string(value);
}

std::string toStringValue(const int32_t &value){
return std::to_string(value);
}

std::string toStringValue(const int64_t &value){
return std::to_string(value);
}

std::string toStringValue(const bool &value){
return value?std::string("true"):std::string("false");
}

std::string toStringValue(const float &value){
return std::to_string(value);
}

std::string toStringValue(const double &value){
return std::to_string(value);
}

bool fromStringValue(const std::string &inStr, std::string &value){
value = std::string(inStr);
return true;
}

bool fromStringValue(const std::string &inStr, int32_t &value){
try {
value = std::stoi( inStr );
}
catch (const std::invalid_argument) {
return false;
}
return true;
}

bool fromStringValue(const std::string &inStr, int64_t &value){
try {
value = std::stol( inStr );
}
catch (const std::invalid_argument) {
return false;
}
return true;
}

bool fromStringValue(const std::string &inStr, bool &value){
bool result = true;
inStr == "true"?value = true: inStr == "false"?value = false: result = false;
return result;
}

bool fromStringValue(const std::string &inStr, float &value){
try {
value = std::stof( inStr );
}
catch (const std::invalid_argument) {
return false;
}
return true;
}

bool fromStringValue(const std::string &inStr, double &value){
try {
value = std::stod( inStr );
}
catch (const std::invalid_argument) {
return false;
}
return true;
}

{{#helpersNamespaceDeclarations}}
}
{{/helpersNamespaceDeclarations}}
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@ void {{classname}}::fromJson(nlohmann::json& val)
}
{{/isListContainer}}{{^isListContainer}}{{^isPrimitiveType}}{{^required}}if(val.find("{{baseName}}") != val.end())
{
{{#isString}}{{setter}}(val.at("{{baseName}}"));{{/isString}}{{#isByteArray}}{{setter}}(val.at("{{baseName}}"));
{{/isByteArray}}{{^isString}}{{#isDateTime}}{{setter}}(val.at("{{baseName}}"));
{{/isDateTime}}{{^isDateTime}}{{^isByteArray}}if(!val["{{baseName}}"].is_null())
{{#isString}}{{setter}}(val.at("{{baseName}}"));{{/isString}}{{#isByteArray}}{{setter}}(val.at("{{baseName}}"));{{/isByteArray}}{{#isBinary}}{{setter}}(val.at("{{baseName}}"));
{{/isBinary}}{{^isString}}{{#isDateTime}}{{setter}}(val.at("{{baseName}}"));
{{/isDateTime}}{{^isDateTime}}{{^isByteArray}}{{^isBinary}}if(!val["{{baseName}}"].is_null())
{
{{{dataType}}} newItem;
newItem.fromJson(val["{{baseName}}"]);
{{setter}}( newItem );
}
{{/isByteArray}}{{/isDateTime}}{{/isString}}
{{/isBinary}}{{/isByteArray}}{{/isDateTime}}{{/isString}}
}
{{/required}}{{#required}}{{#isString}}{{setter}}(val.at("{{baseName}}"));
{{/isString}}{{^isString}}{{#isDateTime}}{{setter}}(val.at("{{baseName}}"));
Expand Down
3 changes: 3 additions & 0 deletions samples/server/petstore/cpp-pistache/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,13 @@ UserApiMainServer.cpp

add_executable(pet_api_server
${PET_API_SERVER_SOURCES})
add_dependencies(pet_api_server PISTACHE NLOHMANN)
add_executable(store_api_server
${STORE_API_SERVER_SOURCES})
add_dependencies(store_api_server PISTACHE NLOHMANN)
add_executable(user_api_server
${USER_API_SERVER_SOURCES})
add_dependencies(user_api_server PISTACHE NLOHMANN)

target_link_libraries(pet_api_server pistache pthread)
target_link_libraries(store_api_server pistache pthread)
Expand Down
20 changes: 18 additions & 2 deletions samples/server/petstore/cpp-pistache/api/PetApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
*/

#include "PetApi.h"
#include "Helpers.h"

namespace org {
namespace openapitools {
namespace server {
namespace api {

using namespace org::openapitools::server::helpers;
using namespace org::openapitools::server::model;

PetApi::PetApi(Pistache::Address addr)
Expand Down Expand Up @@ -94,7 +96,14 @@ void PetApi::delete_pet_handler(const Pistache::Rest::Request &request, Pistache
void PetApi::find_pets_by_status_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {

// Getting the query params
auto status = request.query().get("status");
auto statusQuery = request.query().get("status");
Pistache::Optional<std::vector<std::string>> status;
if(!statusQuery.isEmpty()){
std::vector<std::string> value;
if(fromStringValue(statusQuery.get(), value)){
status = Pistache::Some(value);
}
}

try {
this->find_pets_by_status(status, response);
Expand All @@ -108,7 +117,14 @@ void PetApi::find_pets_by_status_handler(const Pistache::Rest::Request &request,
void PetApi::find_pets_by_tags_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {

// Getting the query params
auto tags = request.query().get("tags");
auto tagsQuery = request.query().get("tags");
Pistache::Optional<std::vector<std::string>> tags;
if(!tagsQuery.isEmpty()){
std::vector<std::string> value;
if(fromStringValue(tagsQuery.get(), value)){
tags = Pistache::Some(value);
}
}

try {
this->find_pets_by_tags(tags, response);
Expand Down
6 changes: 3 additions & 3 deletions samples/server/petstore/cpp-pistache/api/PetApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ using namespace org::openapitools::server::model;
class PetApi {
public:
PetApi(Pistache::Address addr);
virtual ~PetApi() {};
virtual ~PetApi() {}
void init(size_t thr);
void start();
void shutdown();
Expand Down Expand Up @@ -90,7 +90,7 @@ class PetApi {
/// Multiple status values can be provided with comma separated strings
/// </remarks>
/// <param name="status">Status values that need to be considered for filter</param>
virtual void find_pets_by_status(const Pistache::Optional<std::string> &status, Pistache::Http::ResponseWriter &response) = 0;
virtual void find_pets_by_status(const Pistache::Optional<std::vector<std::string>> &status, Pistache::Http::ResponseWriter &response) = 0;

/// <summary>
/// Finds Pets by tags
Expand All @@ -99,7 +99,7 @@ class PetApi {
/// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
/// </remarks>
/// <param name="tags">Tags to filter by</param>
virtual void find_pets_by_tags(const Pistache::Optional<std::string> &tags, Pistache::Http::ResponseWriter &response) = 0;
virtual void find_pets_by_tags(const Pistache::Optional<std::vector<std::string>> &tags, Pistache::Http::ResponseWriter &response) = 0;

/// <summary>
/// Find pet by ID
Expand Down
Loading