Skip to content

Commit 36f4452

Browse files
ybelenkoackintosh
authored andcommitted
[Slim] Upgrade API server integration tests to use Fake Petstore spec (#354)
* [Slim] Shell script points to petstore-with-fake-endpoints-models-for-testing.yaml. Slim init and new models has been generated. * [Slim] Bugfix. Special value */* in opperation produces escaped to avoid PHP syntax errors. * [Slim] Add own private static final LOGGER * [Slim] Bugfix. toModelName method copied from PHPClient codegen which handles Fake Petstore spec much better. * [Slim] Sort operations in supporting files data to avoid shadowing static routes. * [Slim] Mustache index.php update. Params parsing enhanced. * [Slim] Tiny cleanup. Unnecessary empty space removed. * [Slim] Security fix. toOperationId method copied from PhpClientCodegen. * [Slim] Bugfix. formData params parsing restored. * [Slim] Proper .gitignore added to PhpSlimServerCodegen. Vendor folder with all dependencies removed to keep repo more clean. * [Slim] Slim dependency update to 3.10.0. Few test fake endpoints fixed by this upgrade.
1 parent 845df89 commit 36f4452

371 files changed

Lines changed: 1130 additions & 33012 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

bin/php-slim-petstore-server.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ fi
2727

2828
# if you've executed sbt assembly previously it will use that instead.
2929
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
30-
ags="generate -t modules/openapi-generator/src/main/resources/slim -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g php-slim -o samples/server/petstore/php-slim $@"
30+
ags="generate -t modules/openapi-generator/src/main/resources/slim -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g php-slim -o samples/server/petstore/php-slim $@"
3131

3232
java $JAVA_OPTS -jar $executable $ags

bin/windows/php-slim-petstore-server.bat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ If Not Exist %executable% (
55
)
66

77
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
8-
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g php-slim -o samples\server\petstore\php-slim
8+
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g php-slim -o samples\server\petstore\php-slim
99

1010
java %JAVA_OPTS% -jar %executable% %ags%

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PhpSlimServerCodegen.java

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,31 @@
1818
package org.openapitools.codegen.languages;
1919

2020
import org.apache.commons.lang3.StringUtils;
21+
import org.openapitools.codegen.CodegenOperation;
2122
import org.openapitools.codegen.CodegenConfig;
2223
import org.openapitools.codegen.CodegenConstants;
2324
import org.openapitools.codegen.CodegenType;
2425
import org.openapitools.codegen.DefaultCodegen;
2526
import org.openapitools.codegen.SupportingFile;
2627
import org.openapitools.codegen.utils.ModelUtils;
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
2730

2831
import io.swagger.v3.oas.models.media.*;
2932

3033
import java.io.File;
3134
import java.util.Arrays;
35+
import java.util.Map;
36+
import java.util.List;
3237
import java.util.HashMap;
3338
import java.util.HashSet;
3439
import java.util.regex.Matcher;
40+
import java.util.Comparator;
41+
import java.util.Collections;
3542

3643
public class PhpSlimServerCodegen extends DefaultCodegen implements CodegenConfig {
44+
private static final Logger LOGGER = LoggerFactory.getLogger(PhpSlimServerCodegen.class);
45+
3746
protected String invokerPackage;
3847
protected String srcBasePath = "lib";
3948
protected String groupId = "org.openapitools";
@@ -112,6 +121,7 @@ public PhpSlimServerCodegen() {
112121
supportingFiles.add(new SupportingFile("composer.json", packagePath.replace('/', File.separatorChar), "composer.json"));
113122
supportingFiles.add(new SupportingFile("index.mustache", packagePath.replace('/', File.separatorChar), "index.php"));
114123
supportingFiles.add(new SupportingFile(".htaccess", packagePath.replace('/', File.separatorChar), ".htaccess"));
124+
supportingFiles.add(new SupportingFile(".gitignore", packagePath.replace('/', File.separatorChar), ".gitignore"));
115125
}
116126

117127
@Override
@@ -232,9 +242,36 @@ public String toParamName(String name) {
232242

233243
@Override
234244
public String toModelName(String name) {
245+
// remove [
246+
name = name.replaceAll("\\]", "");
247+
248+
// Note: backslash ("\\") is allowed for e.g. "\\DateTime"
249+
name = name.replaceAll("[^\\w\\\\]+", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
250+
251+
// remove dollar sign
252+
name = name.replaceAll("$", "");
253+
235254
// model name cannot use reserved keyword
236255
if (isReservedWord(name)) {
237-
escapeReservedWord(name); // e.g. return => _return
256+
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + name));
257+
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
258+
}
259+
260+
// model name starts with number
261+
if (name.matches("^\\d.*")) {
262+
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + camelize("model_" + name));
263+
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
264+
}
265+
266+
// add prefix and/or suffic only if name does not start wth \ (e.g. \DateTime)
267+
if (!name.matches("^\\\\.*")) {
268+
if (!StringUtils.isEmpty(modelNamePrefix)) {
269+
name = modelNamePrefix + "_" + name;
270+
}
271+
272+
if (!StringUtils.isEmpty(modelNameSuffix)) {
273+
name = name + "_" + modelNameSuffix;
274+
}
238275
}
239276

240277
// camelize the model name
@@ -248,6 +285,22 @@ public String toModelFilename(String name) {
248285
return toModelName(name);
249286
}
250287

288+
@Override
289+
public String toOperationId(String operationId) {
290+
// throw exception if method name is empty
291+
if (StringUtils.isEmpty(operationId)) {
292+
throw new RuntimeException("Empty method name (operationId) not allowed");
293+
}
294+
295+
// method name cannot use reserved keyword, e.g. return
296+
if (isReservedWord(operationId)) {
297+
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + camelize(sanitizeName("call_" + operationId), true));
298+
operationId = "call_" + operationId;
299+
}
300+
301+
return camelize(sanitizeName(operationId), true);
302+
}
303+
251304
public String toPackagePath(String packageName, String basePath) {
252305
packageName = packageName.replace(invokerPackage, ""); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
253306
if (basePath != null && basePath.length() > 0) {
@@ -292,4 +345,44 @@ public String escapeUnsafeCharacters(String input) {
292345
return input.replace("*/", "");
293346
}
294347

348+
@Override
349+
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
350+
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
351+
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
352+
for (CodegenOperation op : operationList) {
353+
if (op.hasProduces) {
354+
// need to escape */* values because they breakes current mustaches
355+
List<Map<String, String>> c = op.produces;
356+
for (Map<String, String> mediaType : c) {
357+
if ("*/*".equals(mediaType.get("mediaType"))) {
358+
mediaType.put("mediaType", "*_/_*");
359+
}
360+
}
361+
}
362+
}
363+
return objs;
364+
}
365+
366+
@Override
367+
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
368+
Map<String, Object> apiInfo = (Map<String, Object>) objs.get("apiInfo");
369+
List<HashMap<String, Object>> apiList = (List<HashMap<String, Object>>) apiInfo.get("apis");
370+
for (HashMap<String, Object> api : apiList) {
371+
HashMap<String, Object> operations = (HashMap<String, Object>) api.get("operations");
372+
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
373+
374+
// Sort operations to avoid static routes shadowing
375+
// ref: https://github.com/nikic/FastRoute/blob/master/src/DataGenerator/RegexBasedAbstract.php#L92-L101
376+
Collections.sort(operationList, new Comparator<CodegenOperation>() {
377+
@Override
378+
public int compare(CodegenOperation one, CodegenOperation another) {
379+
if (one.getHasPathParams() && !another.getHasPathParams()) return 1;
380+
if (!one.getHasPathParams() && another.getHasPathParams()) return -1;
381+
return 0;
382+
}
383+
});
384+
}
385+
return objs;
386+
}
387+
295388
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
composer.phar
2+
/vendor/
3+
4+
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
5+
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
6+
composer.lock

modules/openapi-generator/src/main/resources/slim/index.mustache

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,44 @@ $app = new Slim\App();
1313
* {{httpMethod}} {{nickname}}
1414
* Summary: {{summary}}
1515
* Notes: {{notes}}
16-
{{#hasProduces}} * Output-Formats: [{{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}]{{/hasProduces}}
16+
{{#hasProduces}}
17+
* Output-Formats: [{{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}]
18+
{{/hasProduces}}
1719
*/
1820
$app->{{httpMethod}}('{{{basePathWithoutHost}}}{{{path}}}', function($request, $response, $args) {
19-
{{#hasHeaderParams}}$headers = $request->getHeaders();{{/hasHeaderParams}}
20-
{{#hasQueryParams}}$queryParams = $request->getQueryParams();
21-
{{#queryParams}}${{paramName}} = $queryParams['{{paramName}}'];{{newline}} {{/queryParams}}{{/hasQueryParams}}
22-
{{#hasFormParams}}{{#formParams}}${{paramName}} = $args['{{paramName}}'];{{newline}} {{/formParams}}{{/hasFormParams}}
23-
{{#hasBodyParam}}$body = $request->getParsedBody();{{/hasBodyParam}}
24-
$response->write('How about implementing {{nickname}} as a {{httpMethod}} method ?');
25-
return $response;
26-
});
21+
{{#hasHeaderParams}}
22+
$headers = $request->getHeaders();
23+
{{#headerParams}}
24+
${{paramName}} = $request->hasHeader('{{baseName}}') ? $headers['{{baseName}}'] : null;
25+
{{/headerParams}}
26+
{{/hasHeaderParams}}
27+
{{#hasPathParams}}
28+
{{#pathParams}}
29+
${{paramName}} = $args['{{baseName}}'];
30+
{{/pathParams}}
31+
{{/hasPathParams}}
32+
{{#hasQueryParams}}
33+
$queryParams = $request->getQueryParams();
34+
{{#queryParams}}
35+
${{paramName}} = $request->getQueryParam('{{baseName}}');
36+
{{/queryParams}}
37+
{{/hasQueryParams}}
38+
{{#hasFormParams}}
39+
{{#formParams}}
40+
{{^isFile}}
41+
${{paramName}} = $request->getParsedBodyParam('{{baseName}}');
42+
{{/isFile}}
43+
{{#isFile}}
44+
${{paramName}} = (key_exists('{{baseName}}', $request->getUploadedFiles())) ? $request->getUploadedFiles()['{{baseName}}'] : null;
45+
{{/isFile}}
46+
{{/formParams}}
47+
{{/hasFormParams}}
48+
{{#hasBodyParam}}
49+
$body = $request->getParsedBody();
50+
{{/hasBodyParam}}
51+
$response->write('How about implementing {{nickname}} as a {{httpMethod}} method ?');
52+
return $response;
53+
});
2754

2855
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
2956

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
composer.phar
2+
/vendor/
3+
4+
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
5+
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
6+
composer.lock
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.0.0-SNAPSHOT
1+
3.0.3-SNAPSHOT

0 commit comments

Comments
 (0)