pkmst- Prokarma microservice toolkit for java (#7023)

* Added pkmst-microservice toolkit

* formatted

* replaces tab with blank spaces

* adding documentation folder

* adding documentation folder

* Update readme.mustache

Added feature set offered by pkmst

* updated readme

* Update io.swagger.codegen.CodegenConfig

Arranged pkmstServerCodeGen and SymfonyServerCodegen in aphabatical order

* Update readme.mustache

* renamed according to convention and added typeinfoannotation

* removed tabs

* updated codegen which extends abstractjavacodegen

* Added the script files and rectified the errors

* folder name changed and commons -lang3 version upgraded

* updated readme.mustache

* updated logging filter

* Added petstore to samples and updated the pom for the same

* Added java-pkmst sample to pom.xml.circleci

* updated readme.mustache
This commit is contained in:
sanshuman 2017-12-19 13:42:44 +05:30 committed by William Cheng
parent 7d96f61e5d
commit cb59591eff
109 changed files with 7891 additions and 3 deletions

View File

@ -0,0 +1,34 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/pkmst -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l pkmst -o samples/server/petstore/java-pkmst/ -DhideGenerationTimestamp=true"
echo "Removing files and folders under samples/server/petstore/java-pkmst/src/main"
rm -rf samples/server/petstore/java-pkmst/src/main
find samples/server/petstore/java-pkmst -maxdepth 1 -type f ! -name "README.md" ! -name "pom.xml" ! -name "mvn_test_jdk8_only.sh" ! -name ".swagger-codegen-ignore" -exec rm {} +
java $JAVA_OPTS -jar $executable $ags

View File

@ -0,0 +1,10 @@
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar
If Not Exist %executable% (
mvn clean package
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore.yaml -l pkmst -o samples\server\petstore\java-pkmst
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -0,0 +1,832 @@
package io.swagger.codegen.languages;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenParameter;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenResponse;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import io.swagger.models.Tag;
import io.swagger.models.parameters.FormParameter;
import io.swagger.models.parameters.Parameter;
/**
* Created by prokarma on 04/09/17.
*/
public class JavaPKMSTServerCodegen extends AbstractJavaCodegen {
public static final String FULL_JAVA_UTIL = "fullJavaUtil";
public static final String SUPPORT_JAVA6 = "supportJava6";
public static final String CONFIG_PACKAGE = "configPackage";
public static final String BASE_PACKAGE = "basePackage";
public static final String TITLE = "title";
public static final String WITH_XML = "withXml";
public static final String EUREKA_URI = "eurekaUri";
public static final String ZIPKIN_URI = "zipkinUri";
public static final String SPRINGADMIN_URI = "springBootAdminUri";
protected String projectFolder;
protected String projectTestFolder;
protected String sourceFolder;
protected String testFolder;
protected String basePackage = "com.prokarma.pkmst";
protected String serviceName = "Pkmst";
protected String configPackage = "com.prokarma.pkmst.config";
protected boolean implicitHeaders = false;
protected boolean serializeBigDecimalAsString = false;
protected boolean withXml = false;
protected boolean fullJavaUtil;
protected String javaUtilPrefix = "";
protected Boolean serializableModel = false;
protected String invokerPackage;
protected String title;
protected String eurekaUri;
protected String zipkinUri;
protected String springBootAdminUri;
public JavaPKMSTServerCodegen() {
super();
this.projectFolder = "src" + File.separator + "main";
this.projectTestFolder = "src" + File.separator + "test";
this.sourceFolder = this.projectFolder + File.separator + "java";
this.testFolder = this.projectTestFolder + File.separator + "java";
groupId = "com.prokarma";
artifactId = "pkmst-microservice";
artifactVersion = "1.0.0";
embeddedTemplateDir = templateDir = "pkmst";
apiPackage = "com.prokarma.pkmst.controller";
modelPackage = "com.prokarma.pkmst.model";
invokerPackage = "com.prokarma.pkmst.controller";
additionalProperties.put("jackson", "true");
this.cliOptions.add(new CliOption("groupId", "groupId in generated pom.xml"));
this.cliOptions.add(new CliOption("artifactId", "artifactId in generated pom.xml"));
this.cliOptions.add(new CliOption("artifactVersion", "artifact version in generated pom.xml"));
this.cliOptions.add(new CliOption("basePackage", "base package for java source code"));
this.cliOptions.add(new CliOption("serviceName", "Service Name"));
this.cliOptions.add(new CliOption(TITLE, "server title name or client service name"));
this.cliOptions.add(new CliOption("eurekaUri", "Eureka URI"));
this.cliOptions.add(new CliOption("zipkinUri", "Zipkin URI"));
this.cliOptions.add(new CliOption("springBootAdminUri", "Spring-Boot URI"));
// Middleware config
this.cliOptions.add(new CliOption("pkmstInterceptor", "PKMST Interceptor"));
this.apiTestTemplateFiles.put("api_test.mustache", ".java");
this.modelDocTemplateFiles.remove("model_doc.mustache", ".md");
this.apiDocTemplateFiles.remove("api_doc.mustache", ".md");
}
private static String getAccept(Operation operation) {
String accepts = null;
String defaultContentType = "application/json";
if (operation.getProduces() != null && !operation.getProduces().isEmpty()) {
StringBuilder sb = new StringBuilder();
for (String produces : operation.getProduces()) {
if (defaultContentType.equalsIgnoreCase(produces)) {
accepts = defaultContentType;
break;
} else {
if (sb.length() > 0) {
sb.append(",");
}
sb.append(produces);
}
}
if (accepts == null) {
accepts = sb.toString();
}
} else {
accepts = defaultContentType;
}
return accepts;
}
public CodegenType getTag() {
return CodegenType.SERVER;
}
public String getName() {
return "pkmst";
}
public String getHelp() {
return "Generates a PKMST SpringBoot Server application using the SpringFox integration."
+ " Also enables EurekaServerClient / Zipkin / Spring-Boot admin";
}
public void processOpts() {
super.processOpts();
if (this.additionalProperties.containsKey("basePackage")) {
this.setBasePackage((String) this.additionalProperties.get("basePackage"));
this.setInvokerPackage(this.getBasePackage());
this.apiPackage = this.getBasePackage() + ".controller";
this.modelPackage = this.getBasePackage() + ".model";
this.setConfigPackage(this.getBasePackage() + ".config");
} else {
this.additionalProperties.put(BASE_PACKAGE, basePackage);
this.additionalProperties.put(CONFIG_PACKAGE, this.getConfigPackage());
this.additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
this.additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
this.additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
}
if (this.additionalProperties.containsKey("groupId")) {
this.setGroupId((String) this.additionalProperties.get("groupId"));
} else {
// not set, use to be passed to template
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
}
if (this.additionalProperties.containsKey("artifactId")) {
this.setArtifactId((String) this.additionalProperties.get("artifactId"));
} else {
// not set, use to be passed to template
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
}
if (this.additionalProperties.containsKey("artifactVersion")) {
this.setArtifactVersion((String) this.additionalProperties.get("artifactVersion"));
} else {
// not set, use to be passed to template
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
}
if (this.additionalProperties.containsKey("serviceName")) {
this.setServiceName((String) this.additionalProperties.get("serviceName"));
} else {
// not set, use to be passed to template
additionalProperties.put("serviceName", serviceName);
}
if (this.additionalProperties.containsKey(CodegenConstants.SERIALIZE_BIG_DECIMAL_AS_STRING)) {
this.setSerializeBigDecimalAsString(Boolean.valueOf(
this.additionalProperties.get(CodegenConstants.SERIALIZE_BIG_DECIMAL_AS_STRING).toString()));
}
if (this.additionalProperties.containsKey(CodegenConstants.SERIALIZABLE_MODEL)) {
this.setSerializableModel(
Boolean.valueOf(this.additionalProperties.get(CodegenConstants.SERIALIZABLE_MODEL).toString()));
}
if (this.additionalProperties.containsKey(TITLE)) {
this.setTitle((String) this.additionalProperties.get(TITLE));
}
this.additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, serializableModel);
if (this.additionalProperties.containsKey(FULL_JAVA_UTIL)) {
this.setFullJavaUtil(Boolean.valueOf(this.additionalProperties.get(FULL_JAVA_UTIL).toString()));
}
if (this.additionalProperties.containsKey(EUREKA_URI)) {
this.setEurekaUri((String) this.additionalProperties.get(EUREKA_URI));
}
if (this.additionalProperties.containsKey(ZIPKIN_URI)) {
this.setZipkinUri((String) this.additionalProperties.get(ZIPKIN_URI));
}
if (this.additionalProperties.containsKey(SPRINGADMIN_URI)) {
this.setSpringBootAdminUri((String) this.additionalProperties.get(SPRINGADMIN_URI));
}
if (fullJavaUtil) {
javaUtilPrefix = "java.util.";
}
this.additionalProperties.put(FULL_JAVA_UTIL, fullJavaUtil);
this.additionalProperties.put("javaUtilPrefix", javaUtilPrefix);
this.additionalProperties.put(SUPPORT_JAVA6, false);
this.additionalProperties.put("java8", true);
if (this.additionalProperties.containsKey(WITH_XML)) {
this.setWithXml(Boolean.valueOf(additionalProperties.get(WITH_XML).toString()));
}
this.additionalProperties.put(WITH_XML, withXml);
this.apiTemplateFiles.put("api.mustache", ".java");
this.apiTemplateFiles.put("apiController.mustache", "Controller.java");
this.modelTemplateFiles.put("model.mustache", ".java");
this.supportingFiles.add(new SupportingFile("SpringBootApplication.mustache",
(this.getSourceFolder() + File.separator + this.getBasePackage()).replace(".", File.separator),
this.getServiceName() + "Application" + ".java"));
this.supportingFiles
.add(new SupportingFile("config" + File.separator + "swaggerDocumentationConfig.mustache",
(this.sourceFolder + File.separator + this.getConfigPackage()).replace(".",
java.io.File.separator) + File.separator + "swagger",
"SwaggerDocumentationConfig.java"));
this.supportingFiles.add(new SupportingFile("config" + File.separator + "pkmstproperties.mustache",
(this.sourceFolder + File.separator + this.getConfigPackage()).replace(".", java.io.File.separator)
+ File.separator + "swagger",
"PkmstProperties.java"));
this.supportingFiles.add(new SupportingFile("config" + File.separator + "appconfig.mustache",
(this.sourceFolder + File.separator + this.getConfigPackage()).replace(".", java.io.File.separator)
+ File.separator,
"AppConfig.java"));
// Security
this.supportingFiles
.add(new SupportingFile("security" + File.separator + "authorizationServerConfiguration.mustache",
(this.sourceFolder + File.separator + this.basePackage).replace(".", File.separator)
+ File.separator + "security",
"AuthorizationServerConfiguration.java"));
this.supportingFiles
.add(new SupportingFile("security" + File.separator + "oAuth2SecurityConfiguration.mustache",
(this.sourceFolder + File.separator + this.basePackage).replace(".", File.separator)
+ File.separator + "security",
"OAuth2SecurityConfiguration.java"));
this.supportingFiles
.add(new SupportingFile("security" + File.separator + "resourceServerConfiguration.mustache",
(this.sourceFolder + File.separator + this.basePackage).replace(".", File.separator)
+ File.separator + "security",
"ResourceServerConfiguration.java"));
// logging
this.supportingFiles.add(new SupportingFile("logging" + File.separator + "httpLoggingFilter.mustache",
(this.sourceFolder + File.separator + this.basePackage).replace(".", File.separator) + File.separator
+ "logging",
"HttpLoggingFilter.java"));
// Resources
this.supportingFiles.add(new SupportingFile("resources" + File.separator + "application-local.mustache",
("src.main.resources").replace(".", java.io.File.separator), "application-local.yml"));
this.supportingFiles.add(new SupportingFile("resources" + File.separator + "application-dev.mustache",
("src.main.resources").replace(".", java.io.File.separator), "application-dev.yml"));
this.supportingFiles.add(new SupportingFile("resources" + File.separator + "application-dev-config.mustache",
("src.main.resources").replace(".", java.io.File.separator), "application-dev-config.yml"));
this.supportingFiles.add(new SupportingFile("resources" + File.separator + "bootstrap.mustache",
("src.main.resources").replace(".", java.io.File.separator), "bootstrap.yml"));
// POM
this.supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
// Readme
this.supportingFiles.add(new SupportingFile("readme.mustache", "", "Readme.md"));
// manifest
this.supportingFiles.add(new SupportingFile("manifest.mustache", "", "manifest.yml"));
// docker
this.supportingFiles.add(new SupportingFile("docker.mustache", "", "Dockerfile"));
// logstash
this.supportingFiles.add(new SupportingFile("logstash.mustache", "", "logstash.conf"));
// Cucumber
this.supportingFiles.add(new SupportingFile("cucumber" + File.separator + "executeReport.mustache",
this.testFolder + File.separator + this.basePackage.replace(".", File.separator) + File.separator
+ "cucumber" + File.separator + "report",
"ExecuteReport.java"));
this.supportingFiles.add(new SupportingFile(
"cucumber" + File.separator + "cucumberTest.mustache", this.testFolder + File.separator
+ this.basePackage.replace(".", File.separator) + File.separator + "cucumber",
serviceName + "Test.java"));
this.supportingFiles.add(new SupportingFile(
"cucumber" + File.separator + "cucumberSteps.mustache", this.testFolder + File.separator
+ this.basePackage.replace(".", File.separator) + File.separator + "cucumber",
serviceName + "Steps.java"));
this.supportingFiles.add(new SupportingFile(
"cucumber" + File.separator + "package.mustache", this.testFolder + File.separator
+ this.basePackage.replace(".", File.separator) + File.separator + "cucumber",
serviceName + "package-info.java"));
// test resources
this.supportingFiles.add(new SupportingFile("cucumber" + File.separator + "cucumber.mustache",
(("src.test.resources") + File.separator + this.basePackage).replace(".", File.separator)
+ File.separator + "cucumber",
serviceName + ".feature"));
this.supportingFiles.add(new SupportingFile("testresources" + File.separator + "bootstrap.mustache",
("src.test.resources").replace(".", java.io.File.separator), "bootstrap.yml"));
this.supportingFiles.add(new SupportingFile("testresources" + File.separator + "application.mustache",
("src.test.resources").replace(".", java.io.File.separator), "application.properties"));
this.supportingFiles.add(new SupportingFile("testresources" + File.separator + "application-test.mustache",
("src.test.resources").replace(".", java.io.File.separator), "application-test.properties"));
// Gatling
this.supportingFiles.add(new SupportingFile("gatling" + File.separator + "gatling.mustache",
("src.test.resources").replace(".", java.io.File.separator), "gatling.conf"));
this.supportingFiles.add(new SupportingFile("gatling" + File.separator + "application.mustache",
("src.test.resources").replace(".", java.io.File.separator), "application.conf"));
this.supportingFiles.add(new SupportingFile(
"gatling" + File.separator + "testapi.mustache", ("src") + File.separator + ("test") + File.separator
+ ("scala") + File.separator + ("scalaFiles").replace(".", java.io.File.separator),
"testapi.scala"));
// adding class for integration test
this.supportingFiles.add(new SupportingFile(
"integration" + File.separator + "integrationtest.mustache", this.testFolder + File.separator
+ this.basePackage.replace(".", File.separator) + File.separator + "controller",
serviceName + "IT.java"));
}
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (final CodegenOperation operation : ops) {
List<CodegenResponse> responses = operation.responses;
if (responses != null) {
for (final CodegenResponse resp : responses) {
if ("0".equals(resp.code)) {
resp.code = "200";
}
doDataTypeAssignment(resp.dataType, new DataTypeAssigner() {
public void setReturnType(final String returnType) {
resp.dataType = returnType;
}
public void setReturnContainer(final String returnContainer) {
resp.containerType = returnContainer;
}
});
}
}
doDataTypeAssignment(operation.returnType, new DataTypeAssigner() {
public void setReturnType(final String returnType) {
operation.returnType = returnType;
}
public void setReturnContainer(final String returnContainer) {
operation.returnContainer = returnContainer;
}
});
if (implicitHeaders) {
removeHeadersFromAllParams(operation.allParams);
}
}
}
return objs;
}
/**
* This method removes header parameters from the list of parameters and
* also corrects last allParams hasMore state.
*
* @param allParams
* list of all parameters
*/
private void removeHeadersFromAllParams(List<CodegenParameter> allParams) {
if (allParams.isEmpty()) {
return;
}
final ArrayList<CodegenParameter> copy = new ArrayList<>(allParams);
allParams.clear();
for (CodegenParameter p : copy) {
if (!p.isHeaderParam) {
allParams.add(p);
}
}
allParams.get(allParams.size() - 1).hasMore = false;
}
/**
* @param returnType
* The return type that needs to be converted
* @param dataTypeAssigner
* An object that will assign the data to the respective fields
* in the model.
*/
private void doDataTypeAssignment(String returnType, DataTypeAssigner dataTypeAssigner) {
final String rt = returnType;
if (rt == null) {
dataTypeAssigner.setReturnType("Void");
} else if (rt.startsWith("List")) {
int end = rt.lastIndexOf(">");
if (end > 0) {
dataTypeAssigner.setReturnType(rt.substring("List<".length(), end).trim());
dataTypeAssigner.setReturnContainer("List");
}
} else if (rt.startsWith("Map")) {
int end = rt.lastIndexOf(">");
if (end > 0) {
dataTypeAssigner.setReturnType(rt.substring("Map<".length(), end).split(",")[1].trim());
dataTypeAssigner.setReturnContainer("Map");
}
} else if (rt.startsWith("Set")) {
int end = rt.lastIndexOf(">");
if (end > 0) {
dataTypeAssigner.setReturnType(rt.substring("Set<".length(), end).trim());
dataTypeAssigner.setReturnContainer("Set");
}
}
}
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
super.postProcessModelProperty(model, property);
if ("null".equals(property.example)) {
property.example = null;
}
// Add imports for Jackson
if (!Boolean.TRUE.equals(model.isEnum)) {
model.imports.add("JsonProperty");
if (Boolean.TRUE.equals(model.hasEnums)) {
model.imports.add("JsonValue");
}
} else { // enum class
// Needed imports for Jackson's JsonCreator
if (this.additionalProperties.containsKey("jackson")) {
model.imports.add("JsonCreator");
}
}
}
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
objs = super.postProcessModelsEnum(objs);
// Add imports for Jackson
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
List<Object> models = (List<Object>) objs.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
// for enum model
if (Boolean.TRUE.equals(cm.isEnum) && cm.allowableValues != null) {
cm.imports.add(this.importMapping.get("JsonValue"));
Map<String, String> item = new HashMap<String, String>();
item.put("import", this.importMapping.get("JsonValue"));
imports.add(item);
}
}
return objs;
}
@SuppressWarnings("unchecked")
@Override
public void preprocessSwagger(Swagger swagger) {
super.preprocessSwagger(swagger);
if (swagger == null || swagger.getPaths() == null) {
return;
}
if (swagger.getTags() != null) {
List<ResourcePath> resourcePaths = new ArrayList<>();
for (Tag tag : swagger.getTags()) {
ResourcePath resourcePath = new ResourcePath();
resourcePath.setPath(tag.getName());
resourcePaths.add(resourcePath);
}
this.additionalProperties.put("resourcePaths", resourcePaths);
}
// get vendor extensions
Map<String, Object> vendorExt = swagger.getInfo().getVendorExtensions();
if (vendorExt != null && !vendorExt.toString().equals("")) {
if (vendorExt.containsKey("x-codegen")) {
Map<String, String> uris = (Map<String, String>) vendorExt.get("x-codegen");
if (uris.containsKey("eurekaUri")) {
String eurekaUri = uris.get("eurekaUri");
additionalProperties.put(EUREKA_URI, eurekaUri);
}
if (uris.containsKey("zipkinUri")) {
String zipkinUri = uris.get("zipkinUri");
additionalProperties.put(ZIPKIN_URI, zipkinUri);
}
if (uris.containsKey("springBootAdminUri")) {
String springBootAdminUri = uris.get("springBootAdminUri");
additionalProperties.put(SPRINGADMIN_URI, springBootAdminUri);
}
if (uris.containsKey("pkmstInterceptor")) {
String pkmstInterceptor = uris.get("pkmstInterceptor");
additionalProperties.put("pkmstInterceptor", pkmstInterceptor);
}
}
}
for (String pathname : swagger.getPaths().keySet()) {
Path path = swagger.getPath(pathname);
if (path.getOperations() == null) {
continue;
}
for (Operation operation : path.getOperations()) {
boolean hasFormParameters = false;
for (Parameter parameter : operation.getParameters()) {
if (parameter instanceof FormParameter) {
hasFormParameters = true;
}
}
// only add content-Type if its no a GET-Method
if (path.getGet() != null || !operation.equals(path.getGet())) {
String defaultContentType = hasFormParameters ? "application/x-www-form-urlencoded"
: "application/json";
String contentType = operation.getConsumes() == null || operation.getConsumes().isEmpty()
? defaultContentType : operation.getConsumes().get(0);
operation.setVendorExtension("x-contentType", contentType);
}
String accepts = getAccept(operation);
operation.setVendorExtension("x-accepts", accepts);
}
}
if ("/".equals(swagger.getBasePath())) {
swagger.setBasePath("");
}
if (!additionalProperties.containsKey(TITLE)) {
// From the title, compute a reasonable name for the package and the
// API
String title = swagger.getInfo().getTitle();
// Drop any API suffix
if (title != null) {
title = title.trim().replace(" ", "-");
if (title.toUpperCase().endsWith("API")) {
title = title.substring(0, title.length() - 3);
}
this.title = camelize(sanitizeName(title), true);
}
additionalProperties.put(TITLE, this.title);
}
String host = swagger.getHost();
String port = "8008";
if (host != null) {
String[] parts = host.split(":");
if (parts.length > 1) {
port = parts[1];
}
}
this.additionalProperties.put("serverPort", port);
if (swagger.getPaths() != null) {
for (String pathname : swagger.getPaths().keySet()) {
Path path = swagger.getPath(pathname);
if (path.getOperations() != null) {
for (Operation operation : path.getOperations()) {
if (operation.getTags() != null) {
List<Map<String, String>> tags = new ArrayList<Map<String, String>>();
for (String tag : operation.getTags()) {
Map<String, String> value = new HashMap<String, String>();
value.put("tag", tag);
value.put("hasMore", "true");
tags.add(value);
}
if (tags.size() > 0) {
tags.get(tags.size() - 1).remove("hasMore");
}
if (operation.getTags().size() > 0) {
String tag = operation.getTags().get(0);
operation.setTags(Arrays.asList(tag));
}
operation.setVendorExtension("x-tags", tags);
}
}
}
}
}
}
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co,
Map<String, List<CodegenOperation>> operations) {
super.addOperationToGroup(tag, resourcePath, operation, co, operations);
co.subresourceOperation = !co.path.isEmpty();
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultApi";
}
name = sanitizeName(name);
return camelize(name) + "Api";
}
@Override
public String apiFileFolder() {
return this.outputFolder + "/" + this.sourceFolder + "/" + apiPackage().replace(".", "/");
}
@Override
public String apiTestFileFolder() {
return this.outputFolder + "/" + this.testFolder + "/" + apiPackage().replace(".", "/");
}
@Override
public String modelFileFolder() {
return this.outputFolder + "/" + this.sourceFolder + "/" + modelPackage().replace(".", "/");
}
@Override
public String apiDocFileFolder() {
return (this.outputFolder + "/" + this.apiDocPath).replace("/", File.separator);
}
@Override
public String modelDocFileFolder() {
return (this.outputFolder + "/" + this.modelDocPath).replace("/", File.separator);
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getArtifactId() {
return artifactId;
}
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}
public String getArtifactVersion() {
return artifactVersion;
}
public void setArtifactVersion(String artifactVersion) {
this.artifactVersion = artifactVersion;
}
public String getProjectFolder() {
return projectFolder;
}
public void setProjectFolder(String projectFolder) {
this.projectFolder = projectFolder;
}
public String getEurekaUri() {
return eurekaUri;
}
public void setEurekaUri(String eurekaUri) {
this.eurekaUri = eurekaUri;
}
public String getZipkinUri() {
return zipkinUri;
}
public void setZipkinUri(String zipkinUri) {
this.zipkinUri = zipkinUri;
}
public String getSpringBootAdminUri() {
return springBootAdminUri;
}
public void setSpringBootAdminUri(String springBootAdminUri) {
this.springBootAdminUri = springBootAdminUri;
}
public String getProjectTestFolder() {
return projectTestFolder;
}
public void setProjectTestFolder(String projectTestFolder) {
this.projectTestFolder = projectTestFolder;
}
public String getSourceFolder() {
return sourceFolder;
}
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
public String getTestFolder() {
return testFolder;
}
public void setTestFolder(String testFolder) {
this.testFolder = testFolder;
}
public String getBasePackage() {
return basePackage;
}
public void setBasePackage(String basePackage) {
this.basePackage = basePackage;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getConfigPackage() {
return configPackage;
}
public void setConfigPackage(String configPackage) {
this.configPackage = configPackage;
}
public boolean isImplicitHeaders() {
return implicitHeaders;
}
public void setImplicitHeaders(boolean implicitHeaders) {
this.implicitHeaders = implicitHeaders;
}
public boolean isSerializeBigDecimalAsString() {
return serializeBigDecimalAsString;
}
public void setSerializeBigDecimalAsString(boolean serializeBigDecimalAsString) {
this.serializeBigDecimalAsString = serializeBigDecimalAsString;
}
public boolean isFullJavaUtil() {
return fullJavaUtil;
}
public void setFullJavaUtil(boolean fullJavaUtil) {
this.fullJavaUtil = fullJavaUtil;
}
public Boolean getSerializableModel() {
return serializableModel;
}
public void setSerializableModel(Boolean serializableModel) {
this.serializableModel = serializableModel;
}
public String getInvokerPackage() {
return invokerPackage;
}
public void setInvokerPackage(String invokerPackage) {
this.invokerPackage = invokerPackage;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public boolean isWithXml() {
return withXml;
}
public void setWithXml(boolean withXml) {
this.withXml = withXml;
}
private interface DataTypeAssigner {
void setReturnType(String returnType);
void setReturnContainer(String returnContainer);
}
private class ResourcePath {
private String path;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
@Override
public String toString() {
return this.path;
}
}
}

View File

@ -33,6 +33,7 @@ io.swagger.codegen.languages.JavaJAXRSSpecServerCodegen
io.swagger.codegen.languages.JavaJerseyServerCodegen io.swagger.codegen.languages.JavaJerseyServerCodegen
io.swagger.codegen.languages.JavaJerseyServerCodegen io.swagger.codegen.languages.JavaJerseyServerCodegen
io.swagger.codegen.languages.JavaMSF4JServerCodegen io.swagger.codegen.languages.JavaMSF4JServerCodegen
io.swagger.codegen.languages.JavaPKMSTServerCodegen
io.swagger.codegen.languages.JavaPlayFrameworkCodegen io.swagger.codegen.languages.JavaPlayFrameworkCodegen
io.swagger.codegen.languages.JavaResteasyEapServerCodegen io.swagger.codegen.languages.JavaResteasyEapServerCodegen
io.swagger.codegen.languages.JavaResteasyServerCodegen io.swagger.codegen.languages.JavaResteasyServerCodegen
@ -47,7 +48,6 @@ io.swagger.codegen.languages.NodeJSServerCodegen
io.swagger.codegen.languages.ObjcClientCodegen io.swagger.codegen.languages.ObjcClientCodegen
io.swagger.codegen.languages.PerlClientCodegen io.swagger.codegen.languages.PerlClientCodegen
io.swagger.codegen.languages.PhpClientCodegen io.swagger.codegen.languages.PhpClientCodegen
io.swagger.codegen.languages.SymfonyServerCodegen
io.swagger.codegen.languages.PowerShellClientCodegen io.swagger.codegen.languages.PowerShellClientCodegen
io.swagger.codegen.languages.PistacheServerCodegen io.swagger.codegen.languages.PistacheServerCodegen
io.swagger.codegen.languages.PythonClientCodegen io.swagger.codegen.languages.PythonClientCodegen
@ -74,6 +74,7 @@ io.swagger.codegen.languages.SwaggerYamlGenerator
io.swagger.codegen.languages.Swift4Codegen io.swagger.codegen.languages.Swift4Codegen
io.swagger.codegen.languages.Swift3Codegen io.swagger.codegen.languages.Swift3Codegen
io.swagger.codegen.languages.SwiftCodegen io.swagger.codegen.languages.SwiftCodegen
io.swagger.codegen.languages.SymfonyServerCodegen
io.swagger.codegen.languages.TizenClientCodegen io.swagger.codegen.languages.TizenClientCodegen
io.swagger.codegen.languages.TypeScriptAureliaClientCodegen io.swagger.codegen.languages.TypeScriptAureliaClientCodegen
io.swagger.codegen.languages.TypeScriptAngularClientCodegen io.swagger.codegen.languages.TypeScriptAngularClientCodegen

View File

@ -0,0 +1,20 @@
package {{basePackage}};
import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
import com.fasterxml.jackson.databind.util.ISO8601Utils;
import java.text.FieldPosition;
import java.util.Date;
public class RFC3339DateFormat extends ISO8601DateFormat {
// Same as ISO8601DateFormat but serializing milliseconds.
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
String value = ISO8601Utils.format(date, true);
toAppendTo.append(value);
return toAppendTo;
}
}

View File

@ -0,0 +1,36 @@
package {{basePackage}};
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
{{#eurekaUri}}
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
{{/eurekaUri}}
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* starts the spring boot application
* @author pkmst
*
*/
@SpringBootApplication
@EnableSwagger2
{{#eurekaUri}}
@EnableEurekaClient
{{/eurekaUri}}
@EnableCircuitBreaker
@EnableHystrixDashboard
public class {{serviceName}}Application {
private static final Logger LOGGER = LoggerFactory.getLogger({{serviceName}}Application.class);
public static void main(String[] args) {
LOGGER.debug("Running spring boot application");
SpringApplication.run({{serviceName}}Application.class, args);
}
}

View File

@ -0,0 +1,87 @@
/**
* NOTE: This class is auto generated by the swagger code generator program ({{{generatorVersion}}}).
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
package {{package}};
{{#imports}}import {{import}};
{{/imports}}
import io.swagger.annotations.*;
{{#jdk8}}
import org.springframework.http.HttpStatus;
{{/jdk8}}
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
{{^useSpringCloudClient}}
import java.io.IOException;
{{/useSpringCloudClient}}
import java.util.List;
{{#useOptional}}
import java.util.Optional;
{{/useOptional}}
{{#async}}
import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}};
{{/async}}
{{#useBeanValidation}}
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.*;
import javax.validation.Valid;
{{/useBeanValidation}}
/**
* Provides the info about api methods
* @author pkmst
*
*/
{{>generatedAnnotation}}
@Api(value = "{{{baseName}}}", description = "the {{{baseName}}} API")
{{#operations}}
public interface {{classname}} {
{{#operation}}
@ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}", response = {{{returnType}}}.class{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = {
{{#authMethods}}@Authorization(value = "{{name}}"{{#isOAuth}}, scopes = {
{{#scopes}}@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{#hasMore}},
{{/hasMore}}{{/scopes}}
}{{/isOAuth}}){{#hasMore}},
{{/hasMore}}{{/authMethods}}
}{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}",{{/vendorExtensions.x-tags}} })
@ApiResponses(value = { {{#responses}}
@ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{baseType}}}.class{{/baseType}}{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}){{#hasMore}},{{/hasMore}}{{/responses}} })
{{#implicitHeaders}}
@ApiImplicitParams({
{{#headerParams}}{{>implicitHeader}}{{/headerParams}}
})
{{/implicitHeaders}}
@RequestMapping(value = "{{{path}}}",{{#singleContentTypes}}
produces = "{{{vendorExtensions.x-accepts}}}",
consumes = "{{{vendorExtensions.x-contentType}}}",{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}}
produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}{{#hasConsumes}}
consumes = { {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}{{/singleContentTypes}}
method = RequestMethod.{{httpMethod}})
{{#useSpringCloudClient}}
{{#jdk8}}default {{/jdk8}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/allParams}}){{^jdk8}};{{/jdk8}}{{#jdk8}} {
// do some magic!
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<{{>returnTypes}}>(HttpStatus.NOT_IMPLEMENTED){{#async}}){{/async}};
}{{/jdk8}}
{{/useSpringCloudClient}}
{{^useSpringCloudClient}}
{{#jdk8}}default {{/jdk8}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}},{{/allParams}} @RequestHeader(value = "Accept", required = false) String accept) throws Exception{{^jdk8}};{{/jdk8}}{{#jdk8}} {
// do some magic!
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK){{#async}}){{/async}};
}{{/jdk8}}
{{/useSpringCloudClient}}
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,115 @@
package {{package}};
{{^jdk8-no-delegate}}
{{#imports}}import {{import}};
{{/imports}}
import io.swagger.annotations.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
{{/jdk8-no-delegate}}
import org.springframework.stereotype.Controller;
{{^jdk8-no-delegate}}
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
{{#useOptional}}
import java.util.Optional;
{{/useOptional}}
{{#async}}
import java.util.concurrent.Callable;
{{/async}}
{{/jdk8-no-delegate}}
{{^useSpringCloudClient}}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
{{/useSpringCloudClient}}
{{#useBeanValidation}}
import javax.validation.constraints.*;
import javax.validation.Valid;
{{/useBeanValidation}}
/**
* Api implemention
* @author pkmst
*
*/
{{>generatedAnnotation}}
@Controller
{{#operations}}
public class {{classname}}Controller implements {{classname}} {
private final ObjectMapper objectMapper;
@Autowired
public {{classname}}Controller(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
{{#isDelegate}}
private final {{classname}}Delegate delegate;
@org.springframework.beans.factory.annotation.Autowired
public {{classname}}Controller({{classname}}Delegate delegate) {
this.delegate = delegate;
}
{{/isDelegate}}
{{^jdk8-no-delegate}}
{{#operation}}
public {{#async}}Callable<{{/async}}ResponseEntity<{{>returnTypes}}>{{#async}}>{{/async}} {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}},
{{/allParams}}@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
{{#useSpringCloudClient}}
{{^isDelegate}}
{{^async}}
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK);
{{/async}}
{{#async}}
return new Callable<ResponseEntity<{{>returnTypes}}>>() {
@Override
public ResponseEntity<{{>returnTypes}}> call() throws Exception {
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK);
}
};
{{/async}}
{{/isDelegate}}
{{#isDelegate}}
return delegate.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/isDelegate}}
{{/useSpringCloudClient}}
{{^useSpringCloudClient}}
{{^isDelegate}}
{{^async}}
{{#examples}}
if (accept != null && accept.contains("{{{contentType}}}")) {
return new ResponseEntity<{{>returnTypes}}>(objectMapper.readValue("{{#lambdaRemoveLineBreak}}{{#lambdaEscapeDoubleQuote}}{{{example}}}{{/lambdaEscapeDoubleQuote}}{{/lambdaRemoveLineBreak}}", {{>exampleReturnTypes}}.class), HttpStatus.OK);
}
{{/examples}}
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK);
{{/async}}
{{#async}}
return new Callable<ResponseEntity<{{>returnTypes}}>>() {
@Override
public ResponseEntity<{{>returnTypes}}> call() throws Exception {
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK);
}
};
{{/async}}
{{/isDelegate}}
{{#isDelegate}}
return delegate.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/isDelegate}}
{{/useSpringCloudClient}}
}
{{/operation}}
{{/jdk8-no-delegate}}
}
{{/operations}}

View File

@ -0,0 +1,57 @@
{{>licenseInfo}}
package {{package}};
import com.fasterxml.jackson.databind.ObjectMapper;
{{#imports}}import {{import}};
{{/imports}}
import org.junit.Test;
import org.junit.Ignore;
{{^fullJavaUtil}}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
{{/fullJavaUtil}}
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
/**
* API tests for {{classname}}
*/
@Ignore
public class {{classname}}Test {
private final ObjectMapper objectMapper = new ObjectMapper();
private final {{classname}} api = new {{classname}}Controller(objectMapper);
private final String accept = "application/json";
{{#operations}}{{#operation}}
/**
* {{summary}}
*
* {{notes}}
*
* @throws Exception
* if the Api call fails
*/
@Test
public void {{operationId}}Test() throws Exception {
{{#allParams}}
{{^isFile}}
{{{dataType}}} {{paramName}} = null;
{{/isFile}}
{{#isFile}}
MultipartFile {{paramName}} = null;
{{/isFile}}
{{/allParams}}
ResponseEntity<{{>returnTypes}}> response = api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}} {{#allParams}}{{^hasMore}},{{/hasMore}}{{/allParams}} accept);
// TODO: test validations
}
{{/operation}}{{/operations}}
}

View File

@ -0,0 +1,6 @@
{{#required}}
@NotNull
{{/required}}{{#isContainer}}{{^isPrimitiveType}}{{^isEnum}}
@Valid{{/isEnum}}{{/isPrimitiveType}}{{/isContainer}}{{#isNotContainer}}{{^isPrimitiveType}}
@Valid{{/isPrimitiveType}}{{/isNotContainer}}
{{>beanValidationCore}}

View File

@ -0,0 +1 @@
{{! PathParam is always required, no @NotNull necessary }}{{>beanValidationCore}}

View File

@ -0,0 +1 @@
{{#required}}@NotNull {{/required}}{{>beanValidationCore}}

View File

@ -0,0 +1 @@
{{#isBodyParam}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}} {{^isContainer}}{{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{/allowableValues}}{{/isContainer}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestBody {{{dataType}}} {{paramName}}{{/isBodyParam}}

View File

@ -0,0 +1,101 @@
package {{basePackage}}.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
{{#pkmstInterceptor}}
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import com.prokarma.pkmst.interceptor.AuditInterceptor;
import com.prokarma.pkmst.interceptor.BodyInterceptor;
//import com.prokarma.pkmst.interceptor.CorrelationInterceptor;
import com.prokarma.pkmst.interceptor.RateLimitInterceptor;
import com.prokarma.pkmst.interceptor.TraceabilityInterceptor;
{{/pkmstInterceptor}}
/**
* Registers the interceptors which are configurable via yaml
* @author pkmst
*
*/
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
{{#pkmstInterceptor}}
@Value("${interceptor.enable.traceability:false}")
boolean traceabilityEnable;
@Bean
public HandlerInterceptor traceabilityInterceptor() {
return new TraceabilityInterceptor();
}
@Value("${interceptor.enable.correlation:false}")
boolean correlationEnable;
/*@Bean
public HandlerInterceptor correlationInterceptor() {
return new CorrelationInterceptor();
}*/
@Value("${interceptor.enable.rateLimit:false}")
boolean rateLimitEnable;
@Bean
public HandlerInterceptor rateLimitInterceptor() {
return new RateLimitInterceptor();
}
@Value("${interceptor.enable.audit:false}")
boolean auditEnable;
@Bean
public HandlerInterceptor auditInterceptor() {
return new AuditInterceptor();
}
@Value("${interceptor.enable.body:false}")
boolean bodyEnable;
@Bean
public HandlerInterceptor bodyInterceptor() {
return new BodyInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
if (traceabilityEnable) {
registry.addInterceptor(traceabilityInterceptor());
}
if (correlationEnable) {
// registry.addInterceptor(correlationInterceptor);
}
if (rateLimitEnable) {
registry.addInterceptor(rateLimitInterceptor());
}
if (auditEnable) {
registry.addInterceptor(auditInterceptor());
}
if (bodyEnable) {
registry.addInterceptor(bodyInterceptor());
}
}
{{/pkmstInterceptor}}
/**
* enabling cors support at global level which can be applied at various
* level also as below registry.addMapping("/api/**")
* .allowedOrigins("http://domain2.com") .allowedMethods("PUT", "DELETE")
* .allowedHeaders("header1", "header2", "header3")
* .exposedHeaders("header1", "header2")
* .allowCredentials(false).maxAge(3600);
*
* @return
*/
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
};
}
}

View File

@ -0,0 +1,113 @@
package {{basePackage}}.config.swagger;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* Provides the swagger API info
* @author pkmst
*
*/
@Configuration
@ConfigurationProperties(prefix = "pkmst", ignoreUnknownFields = false)
public class PkmstProperties {
private final Swagger swagger = new Swagger();
public Swagger getSwagger() {
return swagger;
}
public static class Swagger {
private String title = "Pkmst API";
private String description = "Pkmst API documentation";
private String version = "0.0.1";
private String termsOfServiceUrl;
private String contactName;
private String contactUrl;
private String contactEmail;
private String license;
private String licenseUrl;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getTermsOfServiceUrl() {
return termsOfServiceUrl;
}
public void setTermsOfServiceUrl(String termsOfServiceUrl) {
this.termsOfServiceUrl = termsOfServiceUrl;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public String getContactUrl() {
return contactUrl;
}
public void setContactUrl(String contactUrl) {
this.contactUrl = contactUrl;
}
public String getContactEmail() {
return contactEmail;
}
public void setContactEmail(String contactEmail) {
this.contactEmail = contactEmail;
}
public String getLicense() {
return license;
}
public void setLicense(String license) {
this.license = license;
}
public String getLicenseUrl() {
return licenseUrl;
}
public void setLicenseUrl(String licenseUrl) {
this.licenseUrl = licenseUrl;
}
}
}

View File

@ -0,0 +1,61 @@
package {{basePackage}}.config.swagger;
import java.util.Date;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StopWatch;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
//import static springfox.documentation.builders.PathSelectors.regex;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Enable swagger ui for application
* @author pkmst
*
*/
@EnableSwagger2
@Configuration
public class SwaggerDocumentationConfig {
public static final String DEFAULT_INCLUDE_PATTERN = "/pkmst/.*";
@Bean
public Docket swaggerSpringfoxDocket(PkmstProperties pkmstProperties) {
StopWatch watch = new StopWatch();
watch.start();
Contact contact = new Contact(
pkmstProperties.getSwagger().getContactName(),
pkmstProperties.getSwagger().getContactUrl(),
pkmstProperties.getSwagger().getContactEmail());
ApiInfo apiInfo = new ApiInfo(
pkmstProperties.getSwagger().getTitle(),
pkmstProperties.getSwagger().getDescription(),
pkmstProperties.getSwagger().getVersion(),
pkmstProperties.getSwagger().getTermsOfServiceUrl(),
contact,
pkmstProperties.getSwagger().getLicense(),
pkmstProperties.getSwagger().getLicenseUrl());
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo)
.forCodeGeneration(true)
.genericModelSubstitutes(ResponseEntity.class)
.ignoredParameterTypes(java.sql.Date.class)
.directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class)
.directModelSubstitute(java.time.ZonedDateTime.class, Date.class)
.directModelSubstitute(java.time.LocalDateTime.class, Date.class)
.select()
.apis(RequestHandlerSelectors.basePackage("com.prokarma.pkmst"))
// .paths(regex(DEFAULT_INCLUDE_PATTERN))
.paths(PathSelectors.any())
.build();
watch.stop();
return docket;
}
}

View File

@ -0,0 +1,33 @@
#Feature: List of scenarios.
#Scenario: Business rule through list of steps with arguments.
#Given: Some precondition step
#When: Some key actions
#Then: To observe outcomes or validation
#And,But: To enumerate more Given,When,Then steps
#Scenario Outline: List of steps for data-driven as an Examples and <placeholder>
#Sample Feature Definition Template
@tag
Feature: Title of your feature
I want to use this template for my feature file
@tag1
Scenario: Title of your scenario
Given I want to write a step with precondition
And some other precondition
When I complete action
And some other action
And yet another action
Then I validate the outcomes
And check more outcomes
@tag2
Scenario Outline: Title of your scenario outline
Given I want to write a step with <name>
When I check for the <value> in step
Then I verify the <status> in step
Examples:
| name |value | status |
| name1 | 5 | success|
| name2 | 7 | Fail |

View File

@ -0,0 +1,76 @@
package {{basePackage}}.cucumber;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import cucumber.api.PendingException;
public class {{serviceName}}Steps {
@Given("^I want to write a step with precondition$")
public void i_want_to_write_a_step_with_precondition() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Given("^some other precondition$")
public void some_other_precondition() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@When("^I complete action$")
public void i_complete_action() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@When("^some other action$")
public void some_other_action() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@When("^yet another action$")
public void yet_another_action() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Then("^I validate the outcomes$")
public void i_validate_the_outcomes() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Then("^check more outcomes$")
public void check_more_outcomes() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Given("^I want to write a step with name(\\d+)$")
public void i_want_to_write_a_step_with_name(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@When("^I check for the (\\d+) in step$")
public void i_check_for_the_in_step(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Then("^I verify the success in step$")
public void i_verify_the_success_in_step() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Then("^I verify the Fail in step$")
public void i_verify_the_Fail_in_step() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
}

View File

@ -0,0 +1,15 @@
package {{basePackage}}.cucumber;
import org.junit.runner.RunWith;
import org.springframework.test.context.ActiveProfiles;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
@RunWith(Cucumber.class)
@ActiveProfiles("test")
@CucumberOptions(format = { "pretty", "html:target/cucumber-html-report",
{{#resourcePaths}}
"json:./report/{{path}}-report-json/{{path}}.json",
{{/resourcePaths}} })
public class {{serviceName}}Test {
}

View File

@ -0,0 +1,42 @@
package {{basePackage}}.cucumber.report;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import net.masterthought.cucumber.Configuration;
import net.masterthought.cucumber.ReportBuilder;
public class ExecuteReport {
public static void main(String[] args) {
generateReport();
}
private static void generateReport() {
String buildNumber = "1";
String projectName = "Spring-micro-sample";
boolean runWithJenkins = false;
boolean parallelTesting = false;
File reportOutputDirectory = null;
List<String> jsonFiles = null;
Configuration configuration = null;
ReportBuilder reportBuilder = null;
{{#resourcePaths}}
reportOutputDirectory = new File("./report/{{path}}-report-html/");
jsonFiles = new ArrayList();
jsonFiles.add("./report/{{path}}-report-json/{{path}}.json");
configuration = new Configuration(reportOutputDirectory,projectName);
// optionally only if you need
configuration.setParallelTesting(parallelTesting);
configuration.setRunWithJenkins(runWithJenkins);
configuration.setBuildNumber(buildNumber);
reportBuilder = new ReportBuilder(jsonFiles, configuration);
reportBuilder.generateReports();
{{/resourcePaths}}
}
}

View File

@ -0,0 +1,2 @@
package {{basePackage}}.cucumber;
//Implement the feature file steps in this package.

View File

@ -0,0 +1,3 @@
FROM frolvlad/alpine-oraclejdk8:slim
COPY target/{{artifactId}}.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -0,0 +1,44 @@
/**
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
*/
public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} {
{{#gson}}
{{#allowableValues}}
{{#enumVars}}
@SerializedName({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}
{{/enumVars}}
{{/allowableValues}}
{{/gson}}
{{^gson}}
{{#allowableValues}}
{{#enumVars}}
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}
{{/enumVars}}
{{/allowableValues}}
{{/gson}}
private {{{datatype}}} value;
{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}({{{datatype}}} value) {
this.value = value;
}
@Override
@JsonValue
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue(String text) {
for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (String.valueOf(b.value).equals(text)) {
return b;
}
}
return null;
}
}

View File

@ -0,0 +1,42 @@
{{#jackson}}
import com.fasterxml.jackson.annotation.JsonCreator;
{{/jackson}}
/**
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
*/
public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
{{#gson}}
{{#allowableValues}}{{#enumVars}}
@SerializedName({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
{{/gson}}
{{^gson}}
{{#allowableValues}}{{#enumVars}}
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
{{/gson}}
private {{{dataType}}} value;
{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) {
this.value = value;
}
@Override
@JsonValue
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue(String text) {
for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (String.valueOf(b.value).equals(text)) {
return b;
}
}
return null;
}
}

View File

@ -0,0 +1 @@
{{#returnContainer}}{{#isMapContainer}}Map{{/isMapContainer}}{{#isListContainer}}List{{/isListContainer}}{{/returnContainer}}{{^returnContainer}}{{{returnType}}}{{/returnContainer}}

View File

@ -0,0 +1 @@
{{#isFormParam}}{{#notFile}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, allowableValues="{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @RequestPart(value="{{baseName}}"{{#required}}, required=true{{/required}}{{^required}}, required=false{{/required}}) {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}@ApiParam(value = "file detail") {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestPart("file") MultipartFile {{baseName}}{{/isFile}}{{/isFormParam}}

View File

@ -0,0 +1,14 @@
####################################
# Akka Actor Config File #
####################################
akka {
scheduler {
tick-duration = 50ms
}
}
url="http://localhost:8081"
noOfUsers=10 #Number of Users
deleteProductId=4 #Delete the Product by using productID
getProduct=2 #Get the Product

View File

@ -0,0 +1,157 @@
#########################
# Gatling Configuration #
#########################
# This file contains all the settings configurable for Gatling with their default values
gatling {
core {
#outputDirectoryBaseName = "" # The prefix for each simulation result folder (then suffixed by the report generation timestamp)
#runDescription = "" # The description for this simulation run, displayed in each report
#encoding = "utf-8" # Encoding to use throughout Gatling for file and string manipulation
#simulationClass = "" # The FQCN of the simulation to run (when used in conjunction with noReports, the simulation for which assertions will be validated)
#mute = false # When set to true, don't ask for simulation name nor run description (currently only used by Gatling SBT plugin)
extract {
regex {
#cacheMaxCapacity = 200 # Cache size for the compiled regexes, set to 0 to disable caching
}
xpath {
#cacheMaxCapacity = 200 # Cache size for the compiled XPath queries, set to 0 to disable caching
}
jsonPath {
#cacheMaxCapacity = 200 # Cache size for the compiled jsonPath queries, set to 0 to disable caching
#preferJackson = false # When set to true, prefer Jackson over Boon for JSON-related operations
jackson {
#allowComments = false # Allow comments in JSON files
#allowUnquotedFieldNames = false # Allow unquoted JSON fields names
#allowSingleQuotes = false # Allow single quoted JSON field names
}
}
css {
#cacheMaxCapacity = 200 # Cache size for the compiled CSS selectors queries, set to 0 to disable caching
}
}
timeOut {
#simulation = 8640000 # Absolute timeout, in seconds, of a simulation
}
directory {
#data = src/test/resource/data # Folder where user's data (e.g. files used by Feeders) is located
#bodies = src/test/resource/bodies # Folder where bodies are located
#simulations = user-src/test/java/simulations # Folder where the bundle's simulations are located<
#reportsOnly = "" # If set, name of report folder to look for in order to generate its report
#binaries = "" # If set, name of the folder where compiles classes are located: Defaults to GATLING_HOME/target.
#results = results # Name of the folder where all reports folder are located
}
}
charting {
#noReports = false # When set to true, don't generate HTML reports
#maxPlotPerSeries = 1000 # Number of points per graph in Gatling reports
#accuracy = 10 # Accuracy, in milliseconds, of the report's stats
indicators {
#lowerBound = 800 # Lower bound for the requests' response time to track in the reports and the console summary
#higherBound = 1200 # Higher bound for the requests' response time to track in the reports and the console summary
#percentile1 = 50 # Value for the 1st percentile to track in the reports, the console summary and GraphiteDataWriter
#percentile2 = 75 # Value for the 2nd percentile to track in the reports, the console summary and GraphiteDataWriter
#percentile3 = 95 # Value for the 3rd percentile to track in the reports, the console summary and GraphiteDataWriter
#percentile4 = 99 # Value for the 4th percentile to track in the reports, the console summary and GraphiteDataWriter
}
}
http {
#elFileBodiesCacheMaxCapacity = 200 # Cache size for request body EL templates, set to 0 to disable
#rawFileBodiesCacheMaxCapacity = 200 # Cache size for request body Raw templates, set to 0 to disable
#fetchedCssCacheMaxCapacity = 200 # Cache size for CSS parsed content, set to 0 to disable
#fetchedHtmlCacheMaxCapacity = 200 # Cache size for HTML parsed content, set to 0 to disable
#redirectPerUserCacheMaxCapacity = 200 # Per virtual user cache size for permanent redirects, set to 0 to disable
#expirePerUserCacheMaxCapacity = 200 # Per virtual user cache size for permanent 'Expire' headers, set to 0 to disable
#lastModifiedPerUserCacheMaxCapacity = 200 # Per virtual user cache size for permanent 'Last-Modified' headers, set to 0 to disable
#etagPerUserCacheMaxCapacity = 200 # Per virtual user cache size for permanent ETag headers, set to 0 to disable
#warmUpUrl = "http://gatling.io" # The URL to use to warm-up the HTTP stack (blank means disabled)
#enableGA = true # Very light Google Analytics, please support
ssl {
trustStore {
#type = "" # Type of SSLContext's TrustManagers store
#file = "" # Location of SSLContext's TrustManagers store
#password = "" # Password for SSLContext's TrustManagers store
#algorithm = "" # Algorithm used by SSLContext's TrustManagers store
}
keyStore {
#type = "" # Type of SSLContext's KeyManagers store
#file = "" # Location of SSLContext's KeyManagers store
#password = "" # Password for SSLContext's KeyManagers store
#algorithm = "" # Algorithm used SSLContext's KeyManagers store
}
}
ahc {
#allowPoolingConnections = true # Allow pooling HTTP connections (keep-alive header automatically added)
#allowPoolingSslConnections = true # Allow pooling HTTPS connections (keep-alive header automatically added)
#compressionEnforced = false # Enforce gzip/deflate when Accept-Encoding header is not defined
#connectTimeout = 60000 # Timeout when establishing a connection
#pooledConnectionIdleTimeout = 60000 # Timeout when a connection stays unused in the pool
#readTimeout = 60000 # Timeout when a used connection stays idle
#connectionTTL = -1 # Max duration a connection can stay open (-1 means no limit)
#ioThreadMultiplier = 2 # Number of Netty worker threads per core
#maxConnectionsPerHost = -1 # Max number of connections per host (-1 means no limit)
#maxConnections = -1 # Max number of connections (-1 means no limit)
#maxRetry = 2 # Number of times that a request should be tried again
#requestTimeout = 60000 # Timeout of the requests
#useProxyProperties = false # When set to true, supports standard Proxy System properties
#webSocketTimeout = 60000 # Timeout when a used websocket connection stays idle
#useRelativeURIsWithConnectProxies = true # When set to true, use relative URIs when talking with an SSL proxy or a WebSocket proxy
#acceptAnyCertificate = true # When set to true, doesn't validate SSL certificates
#httpClientCodecMaxInitialLineLength = 4096 # Maximum length of the initial line of the response (e.g. "HTTP/1.0 200 OK")
#httpClientCodecMaxHeaderSize = 8192 # Maximum size, in bytes, of each request's headers
#httpClientCodecMaxChunkSize = 8192 # Maximum length of the content or each chunk
#keepEncodingHeader = true # Don't drop Encoding response header after decoding
#webSocketMaxFrameSize = 10240 # Maximum frame payload size
#httpsEnabledProtocols = "" # Comma separated enabled protocols for HTTPS, if empty use the JDK defaults
#httpsEnabledCipherSuites = "" # Comma separated enabled cipher suites for HTTPS, if empty use the JDK defaults
#sslSessionCacheSize = 20000 # SSLSession cache size (set to 0 to disable)
#sslSessionTimeout = 86400 # SSLSession timeout (default is 24, like Hotspot)
}
}
data {
#writers = "console, file" # The lists of DataWriters to which Gatling write simulation data (currently supported : "console", "file", "graphite", "jdbc")
#reader = file # The DataReader used by the charting engine for reading simulation results
console {
#light = false # When set to true, displays a light version without detailed request stats
}
file {
#bufferSize = 8192 # FileDataWriter's internal data buffer size, in bytes
}
leak {
#noActivityTimeout = 30 # Period, in seconds, for which Gatling may have no activity before considering a leak may be happening
}
jdbc {
db {
#url = "jdbc:mysql://localhost:3306/temp" # The JDBC URL used by the JDBC DataWriter
#username = "root" # The database user used by the JDBC DataWriter
#password = "123123q" # The password for the specified user
}
#bufferSize = 20 # The size for each batch of SQL inserts to send to the database
create {
#createRunRecordTable = "CREATE TABLE IF NOT EXISTS `RunRecords` ( `id` INT NOT NULL AUTO_INCREMENT , `runDate` DATETIME NULL , `simulationId` VARCHAR(45) NULL , `runDescription` VARCHAR(45) NULL , PRIMARY KEY (`id`) )"
#createRequestRecordTable = "CREATE TABLE IF NOT EXISTS `RequestRecords` (`id` int(11) NOT NULL AUTO_INCREMENT, `runId` int DEFAULT NULL, `scenario` varchar(45) DEFAULT NULL, `userId` VARCHAR(30) NULL, `name` varchar(50) DEFAULT NULL, `requestStartDate` bigint DEFAULT NULL, `requestEndDate` bigint DEFAULT NULL, `responseStartDate` bigint DEFAULT NULL, `responseEndDate` bigint DEFAULT NULL, `status` varchar(2) DEFAULT NULL, `message` varchar(4500) DEFAULT NULL, `responseTime` bigint DEFAULT NULL, PRIMARY KEY (`id`) )"
#createScenarioRecordTable = "CREATE TABLE IF NOT EXISTS `ScenarioRecords` (`id` int(11) NOT NULL AUTO_INCREMENT, `runId` int DEFAULT NULL, `scenarioName` varchar(45) DEFAULT NULL, `userId` VARCHAR(30) NULL, `event` varchar(50) DEFAULT NULL, `startDate` bigint DEFAULT NULL, `endDate` bigint DEFAULT NULL, PRIMARY KEY (`id`) )"
#createGroupRecordTable = "CREATE TABLE IF NOT EXISTS `GroupRecords` (`id` int(11) NOT NULL AUTO_INCREMENT, `runId` int DEFAULT NULL, `scenarioName` varchar(45) DEFAULT NULL, `userId` VARCHAR(30) NULL, `entryDate` bigint DEFAULT NULL, `exitDate` bigint DEFAULT NULL, `status` varchar(2) DEFAULT NULL, PRIMARY KEY (`id`) )"
}
insert {
#insertRunRecord = "INSERT INTO RunRecords (runDate, simulationId, runDescription) VALUES (?,?,?)"
#insertRequestRecord = "INSERT INTO RequestRecords (runId, scenario, userId, name, requestStartDate, requestEndDate, responseStartDate, responseEndDate, status, message, responseTime) VALUES (?,?,?,?,?,?,?,?,?,?,?)"
#insertScenarioRecord = "INSERT INTO ScenarioRecords (runId, scenarioName, userId, event, startDate, endDate) VALUES (?,?,?,?,?,?)"
#insertGroupRecord = "INSERT INTO GroupRecords (runId, scenarioName, userId, entryDate, exitDate, status) VALUES (?,?,?,?,?,?)"
}
}
graphite {
#light = false # only send the all* stats
#host = "localhost" # The host where the Carbon server is located
#port = 2003 # The port to which the Carbon server listens to
#protocol = "tcp" # The protocol used to send data to Carbon (currently supported : "tcp", "udp")
#rootPathPrefix = "gatling" # The common prefix of all metrics sent to Graphite
#bufferSize = 8192 # GraphiteDataWriter's internal data buffer size, in bytes
#writeInterval = 1 # GraphiteDataWriter's write interval, in seconds
}
}
}

View File

@ -0,0 +1,41 @@
# Sample gatling test for Get Product. Please implement likewise for your API.
import scala.concurrent.duration._
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
import com.typesafe.config._
import org.springframework.boot.SpringApplication
import org.springframework.context.ConfigurableApplicationContext
class get{{path}} extends Simulation {
val app: ConfigurableApplicationContext = SpringApplication.run(classOf[{{basePackage}}.{{serviceName}}Application])
Runtime.getRuntime.addShutdownHook(new Thread() {
override def run(): Unit = app.stop()
})
val conf = ConfigFactory.load()
val baseUrl = conf.getString("url")
val noOfUsers: Int = conf.getInt("noOfUsers")
val httpProtocol = http
.baseURL(baseUrl)
.inferHtmlResources()
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
.acceptEncodingHeader("gzip, deflate, sdch")
.acceptLanguageHeader("en-US,en;q=0.8")
.userAgentHeader("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36")
val headers_0 = Map(
"Cache-Control" -> "max-age=0",
"Upgrade-Insecure-Requests" -> "1")
val scn = scenario("getProduct")
.exec(http("request_0")
.get("/{{{path}}}")
.headers(headers_0))
setUp(scn.inject(atOnceUsers(noOfUsers))).protocols(httpProtocol)
}

View File

@ -0,0 +1,3 @@
{{^hideGenerationTimestamp}}
@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}")
{{/hideGenerationTimestamp}}

View File

@ -0,0 +1 @@
{{#isHeaderParam}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, allowableValues="{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @RequestHeader(value="{{baseName}}", required={{#required}}true{{/required}}{{^required}}false{{/required}}) {{>optionalDataType}} {{paramName}}{{/isHeaderParam}}

View File

@ -0,0 +1 @@
{{#isHeaderParam}}@ApiImplicitParam(name = "{{{paramName}}}", value = "{{{description}}}", {{#required}}required=true,{{/required}} dataType = "{{{dataType}}}", paramType = "header"){{#hasMore}},{{/hasMore}}{{/isHeaderParam}}

View File

@ -0,0 +1,34 @@
package {{basePackage}}.controller;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import {{basePackage}}.{{serviceName}}Application;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {{serviceName}}Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class {{serviceName}}IT {
@LocalServerPort
private int port;
TestRestTemplate restTemplate = new TestRestTemplate();
HttpHeaders headers = new HttpHeaders();
@Test
public void testYourMethod() {
//add your logic
}
private String createURLWithPort(String uri) {
return "http://localhost:" + port + uri;
}
}

View File

@ -0,0 +1,11 @@
/*
* {{{appName}}}
* {{{appDescription}}}
*
* {{#version}}OpenAPI spec version: {{{version}}}{{/version}}
* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/

View File

@ -0,0 +1,438 @@
package {{basePackage}}.logging;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.WriteListener;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import org.apache.commons.io.output.TeeOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* Implements javax.servlet.Filter and dump the request/response to syslog
* @author pkmst
*
*/
@Component
public class HttpLoggingFilter implements Filter {
private static final Logger log = LoggerFactory.getLogger(HttpLoggingFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
try {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
Map<String, String> requestMap = this.getTypesafeRequestMap(httpServletRequest);
BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpServletRequest);
BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(httpServletResponse);
final StringBuilder logMessage = new StringBuilder(
"REST Request - ").append("[HTTP METHOD:")
.append(httpServletRequest.getMethod())
.append("] [PATH INFO:")
.append(httpServletRequest.getServletPath())
.append("] [REQUEST PARAMETERS:").append(requestMap)
.append("] [REQUEST BODY:")
.append(bufferedRequest.getRequestBody())
.append("] [REMOTE ADDRESS:")
.append(httpServletRequest.getRemoteAddr()).append("]");
long start = System.currentTimeMillis();
chain.doFilter(bufferedRequest, bufferedResponse);
long elapsedTime = System.currentTimeMillis() - start;
String respContent = null;
if (bufferedResponse.getContent() == null || bufferedResponse.getContent() == "") {
respContent = "No data";
} else {
respContent = bufferedResponse.getContent();
}
logMessage.append(" [RESPONSE:").append(respContent)
.append("] [STATUS CODE:")
.append(bufferedResponse.getStatus())
.append("] [Response Time(ms):").append(elapsedTime)
.append("]");
String [] nonLoggingPaths = {"/v2/api-docs","/swagger-resources","/configuration/security","/swagger-ui.html","/webjars"};
String urlPath = httpServletRequest.getRequestURL().toString();
if (! ( Arrays.stream(nonLoggingPaths).parallel().anyMatch(urlPath::contains) )){
log.info(logMessage.toString());
}
} catch (Throwable a) {
log.error(a.getMessage());
a.printStackTrace();
}
}
private Map<String, String> getTypesafeRequestMap(HttpServletRequest request) {
Map<String, String> typesafeRequestMap = new HashMap<String, String>();
Enumeration<?> requestParamNames = request.getParameterNames();
while (requestParamNames.hasMoreElements()) {
String requestParamName = (String) requestParamNames.nextElement();
String requestParamValue;
if (requestParamName.equalsIgnoreCase("password")) {
requestParamValue = "********";
} else {
requestParamValue = request.getParameter(requestParamName);
}
typesafeRequestMap.put(requestParamName, requestParamValue);
}
return typesafeRequestMap;
}
@Override
public void destroy() {
}
private static final class BufferedRequestWrapper extends HttpServletRequestWrapper {
private ByteArrayInputStream bais = null;
private ByteArrayOutputStream baos = null;
private BufferedServletInputStream bsis = null;
private byte[] buffer = null;
public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
super(req);
// Read InputStream and store its content in a buffer.
InputStream is = req.getInputStream();
this.baos = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int read;
while ((read = is.read(buf)) > 0) {
this.baos.write(buf, 0, read);
}
this.buffer = this.baos.toByteArray();
}
@Override
public ServletInputStream getInputStream() {
this.bais = new ByteArrayInputStream(this.buffer);
this.bsis = new BufferedServletInputStream(this.bais);
return this.bsis;
}
String getRequestBody() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(this.getInputStream()));
String line = null;
StringBuilder inputBuffer = new StringBuilder();
do {
line = reader.readLine();
if (null != line) {
inputBuffer.append(line.trim());
}
} while (line != null);
reader.close();
return inputBuffer.toString().trim();
}
}
private static final class BufferedServletInputStream extends ServletInputStream {
private ByteArrayInputStream bais;
public BufferedServletInputStream(ByteArrayInputStream bais) {
this.bais = bais;
}
@Override
public int available() {
return this.bais.available();
}
@Override
public int read() {
return this.bais.read();
}
@Override
public int read(byte[] buf, int off, int len) {
return this.bais.read(buf, off, len);
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
}
public class TeeServletOutputStream extends ServletOutputStream {
private final TeeOutputStream targetStream;
public TeeServletOutputStream(OutputStream one, OutputStream two) {
targetStream = new TeeOutputStream(one, two);
}
@Override
public void write(int arg0) throws IOException {
this.targetStream.write(arg0);
}
public void flush() throws IOException {
super.flush();
this.targetStream.flush();
}
public void close() throws IOException {
super.close();
this.targetStream.close();
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
}
public class BufferedResponseWrapper implements HttpServletResponse {
HttpServletResponse original;
TeeServletOutputStream tee;
ByteArrayOutputStream bos;
public BufferedResponseWrapper(HttpServletResponse response) {
original = response;
}
public String getContent() {
if (bos == null) {
return null;
} else
return bos.toString();
}
public PrintWriter getWriter() throws IOException {
return original.getWriter();
}
public ServletOutputStream getOutputStream() throws IOException {
if (tee == null) {
bos = new ByteArrayOutputStream();
tee = new TeeServletOutputStream(original.getOutputStream(),bos);
}
return tee;
}
@Override
public String getCharacterEncoding() {
return original.getCharacterEncoding();
}
@Override
public String getContentType() {
return original.getContentType();
}
@Override
public void setCharacterEncoding(String charset) {
original.setCharacterEncoding(charset);
}
@Override
public void setContentLength(int len) {
original.setContentLength(len);
}
@Override
public void setContentLengthLong(long l) {
original.setContentLengthLong(l);
}
@Override
public void setContentType(String type) {
original.setContentType(type);
}
@Override
public void setBufferSize(int size) {
original.setBufferSize(size);
}
@Override
public int getBufferSize() {
return original.getBufferSize();
}
@Override
public void flushBuffer() throws IOException {
tee.flush();
}
@Override
public void resetBuffer() {
original.resetBuffer();
}
@Override
public boolean isCommitted() {
return original.isCommitted();
}
@Override
public void reset() {
original.reset();
}
@Override
public void setLocale(Locale loc) {
original.setLocale(loc);
}
@Override
public Locale getLocale() {
return original.getLocale();
}
@Override
public void addCookie(Cookie cookie) {
original.addCookie(cookie);
}
@Override
public boolean containsHeader(String name) {
return original.containsHeader(name);
}
@Override
public String encodeURL(String url) {
return original.encodeURL(url);
}
@Override
public String encodeRedirectURL(String url) {
return original.encodeRedirectURL(url);
}
@SuppressWarnings("deprecation")
@Override
public String encodeUrl(String url) {
return original.encodeUrl(url);
}
@SuppressWarnings("deprecation")
@Override
public String encodeRedirectUrl(String url) {
return original.encodeRedirectUrl(url);
}
@Override
public void sendError(int sc, String msg) throws IOException {
original.sendError(sc, msg);
}
@Override
public void sendError(int sc) throws IOException {
original.sendError(sc);
}
@Override
public void sendRedirect(String location) throws IOException {
original.sendRedirect(location);
}
@Override
public void setDateHeader(String name, long date) {
original.setDateHeader(name, date);
}
@Override
public void addDateHeader(String name, long date) {
original.addDateHeader(name, date);
}
@Override
public void setHeader(String name, String value) {
original.setHeader(name, value);
}
@Override
public void addHeader(String name, String value) {
original.addHeader(name, value);
}
@Override
public void setIntHeader(String name, int value) {
original.setIntHeader(name, value);
}
@Override
public void addIntHeader(String name, int value) {
original.addIntHeader(name, value);
}
@Override
public void setStatus(int sc) {
original.setStatus(sc);
}
@SuppressWarnings("deprecation")
@Override
public void setStatus(int sc, String sm) {
original.setStatus(sc, sm);
}
@Override
public String getHeader(String arg0) {
return original.getHeader(arg0);
}
@Override
public Collection<String> getHeaderNames() {
return original.getHeaderNames();
}
@Override
public Collection<String> getHeaders(String arg0) {
return original.getHeaders(arg0);
}
@Override
public int getStatus() {
return original.getStatus();
}
}
}

View File

@ -0,0 +1,35 @@
input {
file {
path => ""
start_position => "beginning"
}
}
filter {
# pattern matching logback pattern
grok {
}
}
}
output {
# Print each event to stdout, useful for debugging. Should be commented out in production.
# Enabling 'rubydebug' codec on the stdout output will make logstash
# pretty-print the entire event as something similar to a JSON representation.
stdout {
codec => rubydebug
}
# Sending properly parsed log events to elasticsearch
elasticsearch {
hosts => ["localhost:9200"]
}
}

View File

@ -0,0 +1,12 @@
applications:
- name:
memory: 1G
instances: 1
host:
buildpack: https://github.com/cloudfoundry/java-buildpack.git
path:
services:
-
-
env:

View File

@ -0,0 +1,37 @@
package {{package}};
import java.util.Objects;
{{#imports}}import {{import}};
{{/imports}}
{{#serializableModel}}
import java.io.Serializable;
{{/serializableModel}}
{{#useBeanValidation}}
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import javax.validation.constraints.*;
{{/useBeanValidation}}
{{#jackson}}
{{#withXml}}
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
{{/withXml}}
{{/jackson}}
{{#withXml}}
import javax.xml.bind.annotation.*;
{{/withXml}}
/**
* Response class to be returned by Api
* @author pkmst
*
*/
{{#models}}
{{#model}}
{{#isEnum}}
{{>enumOuterClass}}
{{/isEnum}}
{{^isEnum}}
{{>pojo}}
{{/isEnum}}
{{/model}}
{{/models}}

View File

@ -0,0 +1,10 @@
package {{apiPackage}};
{{>generatedAnnotation}}
public class NotFoundException extends ApiException {
private int code;
public NotFoundException (int code, String msg) {
super(code, msg);
this.code = code;
}
}

View File

@ -0,0 +1 @@
{{#useOptional}}{{#required}}{{{dataType}}}{{/required}}{{^required}}Optional<{{{dataType}}}>{{/required}}{{/useOptional}}{{^useOptional}}{{{dataType}}}{{/useOptional}}

View File

@ -0,0 +1 @@
{{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}},required=true{{/required}}{{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{/allowableValues}} {{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @PathVariable("{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isPathParam}}

View File

@ -0,0 +1,140 @@
/**
* {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}}
*/{{#description}}
@ApiModel(description = "{{{description}}}"){{/description}}
{{#useBeanValidation}}@Validated{{/useBeanValidation}}
{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}}
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} {
{{#serializableModel}}
private static final long serialVersionUID = 1L;
{{/serializableModel}}
{{#vars}}
{{#isEnum}}
{{^isContainer}}
{{>enumClass}}
{{/isContainer}}
{{/isEnum}}
{{#items.isEnum}}
{{#items}}
{{^isContainer}}
{{>enumClass}}
{{/isContainer}}
{{/items}}
{{/items.isEnum}}
{{#jackson}}
@JsonProperty("{{baseName}}"){{#withXml}}
@JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}"){{/withXml}}
{{/jackson}}
{{#gson}}
@SerializedName("{{baseName}}")
{{/gson}}
{{#isContainer}}
{{#useBeanValidation}}@Valid{{/useBeanValidation}}
private {{{datatypeWithEnum}}} {{name}}{{#required}} = {{{defaultValue}}}{{/required}}{{^required}} = null{{/required}};
{{/isContainer}}
{{^isContainer}}
private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};
{{/isContainer}}
{{/vars}}
{{#vars}}
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
return this;
}
{{#isListContainer}}
public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) {
{{^required}}
if (this.{{name}} == null) {
this.{{name}} = {{{defaultValue}}};
}
{{/required}}
this.{{name}}.add({{name}}Item);
return this;
}
{{/isListContainer}}
{{#isMapContainer}}
public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) {
{{^required}}
if (this.{{name}} == null) {
this.{{name}} = {{{defaultValue}}};
}
{{/required}}
this.{{name}}.put(key, {{name}}Item);
return this;
}
{{/isMapContainer}}
/**
{{#description}}
* {{{description}}}
{{/description}}
{{^description}}
* Get {{name}}
{{/description}}
{{#minimum}}
* minimum: {{minimum}}
{{/minimum}}
{{#maximum}}
* maximum: {{maximum}}
{{/maximum}}
* @return {{name}}
**/
{{#vendorExtensions.extraAnnotation}}
{{{vendorExtensions.extraAnnotation}}}
{{/vendorExtensions.extraAnnotation}}
@ApiModelProperty({{#example}}example = "{{{example}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}{{#isReadOnly}}readOnly = {{{isReadOnly}}}, {{/isReadOnly}}value = "{{{description}}}")
{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}} public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}
public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
}
{{/vars}}
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}{{#hasVars}}
{{classname}} {{classVarName}} = ({{classname}}) o;
return {{#vars}}Objects.equals(this.{{name}}, {{classVarName}}.{{name}}){{#hasMore}} &&
{{/hasMore}}{{/vars}}{{#parent}} &&
super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}}
return true;{{/hasVars}}
}
@Override
public int hashCode() {
return Objects.hash({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}});
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class {{classname}} {\n");
{{#parent}}sb.append(" ").append(toIndentedString(super.toString())).append("\n");{{/parent}}
{{#vars}}sb.append(" {{name}}: ").append(toIndentedString({{name}})).append("\n");
{{/vars}}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(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,447 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>{{groupId}}</groupId>
<artifactId>{{artifactId}}</artifactId>
<version>{{artifactVersion}}</version>
<packaging>jar</packaging>
<name>{{artifactId}}</name>
<description>Demo project for Spring Boot Microservices</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>1.5.6.RELEASE</spring-boot.version>
<cucumber-junit.version>1.2.5</cucumber-junit.version>
<cucumber-java.version>1.2.5</cucumber-java.version>
<cucumber-reporting.version>3.10.0</cucumber-reporting.version>
<springfox-swagger2>2.6.1-SNAPSHOT</springfox-swagger2>
<springfox-swagger-ui>2.6.0</springfox-swagger-ui>
<slf4j-api>1.7.25</slf4j-api>
<logstash-logback-encoder>4.11</logstash-logback-encoder>
<logback-core>1.2.3</logback-core>
<logback-classic>1.2.3</logback-classic>
<gatling.version>2.3.0</gatling.version>
<gatling-plugin.version>2.2.4</gatling-plugin.version>
<scala-maven-plugin.version>3.2.2</scala-maven-plugin.version>
<spring-cloud.version>Camden.SR7</spring-cloud.version>
<spring-cloud-contract.version>1.1.3.RELEASE</spring-cloud-contract.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath />
<!-- lookup parent from repository -->
</parent>
<repositories>
<repository>
<id>oss-snapshots</id>
<name>JFrog OSS Snapshots</name>
<url>https://oss.jfrog.org/simple/oss-snapshot-local/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>central</id>
<name>Maven Repository Switchboard</name>
<layout>default</layout>
<url>http://repo1.maven.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
</dependency>
{{#eurekaUri}}
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
{{/eurekaUri}}
<!-- dependency for zipkin tracing with sleuth -->
{{#zipkinUri}}
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
{{/zipkinUri}}
<!-- if you only want sleuth -->
<!-- <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency> -->
<!-- Sleuth with Zipkin via Spring Cloud Stream -->
<!-- <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-stream</artifactId>
</dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency> -->
<!-- Spring Cloud Sleuth Stream Zipkin Collector -->
<!-- <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>
</dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency> -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!--<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
{{#springBootAdminUri}}
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>1.2.4</version>
</dependency>
{{/springBootAdminUri}}
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
{{#pkmstInterceptor}}
<!-- PKMST middleware dependency -->
<dependency>
<groupId>com.github.rkumar-pk</groupId>
<artifactId>pkmst-extension</artifactId>
<version>1.0.1</version>
</dependency>
{{/pkmstInterceptor}}
<!-- cucumber dependencies -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber-junit.version}</version>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber-java.version}</version>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-spring</artifactId>
<version>${cucumber-java.version}</version>
</dependency>
<dependency>
<groupId>net.masterthought</groupId>
<artifactId>cucumber-reporting</artifactId>
<version>${cucumber-reporting.version}</version>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>1.46</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-swagger2}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-swagger-ui}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api}</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>${logstash-logback-encoder}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-remote-shell</artifactId>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
<!--Gatling -->
<dependency>
<groupId>io.gatling.highcharts</groupId>
<artifactId>gatling-charts-highcharts</artifactId>
<version>${gatling.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>rest-assured</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.threeten</groupId>
<artifactId>threetenbp</artifactId>
<version>1.3.6</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludes>
<!-- classes that include the name CucumberTest, as an example -->
<exclude>**/*CucumberTest*.java</exclude>
<!-- classes in a package whose last segment is named cucumber, as
an example -->
<exclude>**/cucumber/*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>${scala-maven-plugin.version}</version>
</plugin>
<!--Enable for Gatling -->
<!-- <plugin>
<groupId>io.gatling</groupId>
<artifactId>gatling-maven-plugin</artifactId>
<version>${gatling-plugin.version}</version>
<configuration>
Run Multiple Simulations
<runMultipleSimulations>true</runMultipleSimulations>
<includes>
<simulationClass>testapi</simulationClass>
</includes>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<id>gatling</id>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
</plugin>-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<finalName>${project.name}</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<configuration>
<destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
<dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<reportPlugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
</plugin>
</reportPlugins>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>cucumber-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<!-- Include your Cucumber tests, as an example -->
<include>{{serverName}}Test.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<versionRange>[1.0.1.RELEASE,)</versionRange>
<goals>
<goal>convert</goal>
<goal>generateTests</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -0,0 +1 @@
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{defaultValue}}}"{{/defaultValue}}) {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{>optionalDataType}} {{paramName}}{{/isQueryParam}}

View File

@ -0,0 +1,155 @@
Dear Reader : Thanks for selecting PKMST swagger code generation toolkit for starting your microservice journey.
We believe the hard work we put into this framework will help you kick start your journey sooner and you will find it
easy to scale your service to enterprise grade. Another great thing is you don't need to enable all capabilities as you start,
but can enable as your microservice capabilities needs to be extended to meet strict enterprise standards.
PKMST feature set.
a)Read the Swagger supplied and will create a maven project
b)Create basic controller based on rest verb and path configured in swagger
c)generate default unit test cose using junit
d)generate all needed dependency needed to run the microservice on local
e)generate a default manifest file that allows you to push code to cloudfoundry instance ( eg pcf , ibm bluemix etc)
As you mature your knowledge with pkmst, you can leverage vendor extensions feature that will allow you to supply specific configuration
in your swagger and generate respective configuration that will
f)Allow you integrate with registry server (Example Eureka)
g)Allow you to integrate with tracing server (Example Zipkin)
h)Allow you to capture log in your microservice and send to Log management server (Ex ELK or splunk)
i)Allow you to configure Oauth2 security based authorization for your microservice
Additonal Features
j)generate sample cucumber file and dependency to drive your Behaviour driven development.
k)generate gatling based perfromance test , which can be excuted via build pipeline like jenkins etc.
Working:
Using swagger specification you can convert any definition to spring boot microservice.
It has the integration with the below services:
eureka registry, zipkin , spring boot admin, circuit breaker.
By default only the circuit breaker annotation is enabled. But one has to write the fallback method. The needed dependency for it is also been enabled. To generate the integration and
related configuration for eureka, zipkin, spring boot admin one has two options:
1) When generating from UI one has to provide vendor extensions inside the swagger specification as below:
swagger: "2.0"
info:
description: "This is a sample Product Catalogue Server.\
\ For this sample, you can use the api key `special-key` to test the authorization\
\ filters."
version: "1.0.0"
x-codegen:
eurekaUri: "http://localhost:8080"
zipkinUri: "http://localhost:9411"
springBootAdminUri: "http://localhost:8000"
pkmstInterceptor: "true"
PLease note the vendor extensions are inside the info tag of the swagger specification. All the tags are case sensitive. Once given all the related configuration and the dependency
will be enabled.
2) When generating from the maven plugin one has to provide configuration inside pom as below:
inside the swagger codegen maven plugin under the configuration section
<configuration>
<inputSpec>product-swagger.yaml</inputSpec>
<language>pkmst</language>
<output>${project.build.directory}/generated-sources</output>
<configOptions>
<groupId>com.prokarma</groupId>
<artifactId>product-catalogue</artifactId>
<artifactVersion>1.0</artifactVersion>
<basePackage>com.prokarma.pkmst</basePackage>
<serviceName>ProductCatalogue</serviceName>
<eurekaUri></eurekaUri>
<zipkinUri>http://localhost:9411</zipkinUri>
<springBootAdminUri>http://localhost:4588</springBootAdminUri>
<pkmstInterceptor>true</pkmstInterceptor>
</configOptions>
</configuration>
The project has three profiles local, dev, dev-config which can be configured accordingly. Once you have provided the uris you can see the necessary configurations generated inside the local and the dev
yml files. dev-config is for the config server if you want to use.(also enable the dependency for the config server inside the pom)
[Note: one has to run the zipkin, eureka, spring boot admin servers to be able to connect from the app. This project assumes that you have all the servers
up and running.]
Also provided are the middleware handlers:
1) traceInterceptor:is an id passed in from client and will be unique with an application context. The id will be passed into the backend and return to the consumer for transaction tracing.
2) correlationInterceptor:generates a UUID in the first API/service and pass it to all other APIs/services in the call tree for tracking purpose.
3) rateLimitInterceptor:is a rate limiting handler to limit number of concurrent requests on the server. Once the limit is reached, subsequent requests will be queued for later execution. The size of the queue is configurable.
4) auditInterceptor: audit logs most important info about request and response into audit.log in JSON format with config file that controls which fields to be logged
5) bodyInterceptor:s a body parser middleware that is responsible for parsing the content of the request based on Content-Type in the request header.
To be able to generate the handlers and the necessary configurations one has to provide the pkmstInterceptor key inside the vendor extensions or through
the maven plugin.
Once provided all the handlers are registered in the interceptor registry and can be enabled or disabled through the configuration provided inside
the application yml as below:
interceptor:
enable:
audit: true
body: true
rateLimit: true
traceability: true
correlation: true
For testing we have placeholders for junit test class, integration test class, cucumber sample
feature file(implement according to your needs), gatling load test.
Logstash: Logstash is a tool to collect, process, and forward events and log messages.Sample Logstash configuration file provided that developer can configure to collect wide variety of data.Logstash can dynamically unify data from disparate sources and normalize the data into destinations of their choice.
Ways to run the project:
1) Normal spring boot application
2) Using Dockerfile to run in the container:
dockerfile will be generated inside the project by default. Image can be created using docker cli or through the maven plugin
<build>
<plugins>
...
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>VERSION GOES HERE</version>
<configuration>
<imageName>example</imageName>
<dockerDirectory>docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
...
</plugins>
</build>
Use manifest.yml file to push the application to the cloud.
HttpLogging filter is provided for logging in the request and response. Can be found inside the com.prokarma.pkmst.logging package.
Spring security is also provided to secure the resources. Please modify according to your needs.
First run:
Import the project in to the eclipse. Run the app as an spring boot application.The project will run on http://localhost:8008
Swagger ui available on:
http://localhost:8008/swagger-ui.html
If all the configurations have been enabled(depending on the port) below are some of the URls to access:
eureka: http://localhost:8080
zipkin: http://localhost:9411
Please visit below links for more information on PKMST:
Getting started
https://pkmst-getting-started.mybluemix.net
Pkmst examples
https://github.com/ProKarma-Inc/pkmst-getting-started-examples
Pkmst Extensions
https://github.com/ProKarma-Inc/pkmst-extention

View File

@ -0,0 +1,7 @@
#Enable cloud config. Also enable the dependency in pom
#cloud:
#config:
#uri: {{configUri}}
#fail-fast: true
#password: user
#username: user

View File

@ -0,0 +1,78 @@
# Discovery Server Access
{{#eurekaUri}}
eureka:
instance:
leaseRenewalIntervalInSeconds: 1
leaseExpirationDurationInSeconds: 2
hostname: localhost
healthCheckUrl: http://localhost:{{serverPort}}/health
nonSecurePort: 80
client:
enabled: true
healthcheck:
enabled: true
registerWithEureka: true
#fetchRegistry: true
serviceUrl:
defaultZone: {{eurekaUri}}/eureka/
{{/eurekaUri}}
server:
port: {{serverPort}}
# Spring Actuator
management:
health:
redis:
enabled: false
security:
enabled: false
endpoints:
health:
sensitive: false
info:
app:
name: {{serviceName}}
description: Microservice developed by PKMST
version: {{artifactVersion}}
health:
hystrix:
enabled: true
security:
basic:
enabled: false
# provide rabbitmq configuration
spring:
rabbitmq:
host:
virtual-host:
username:
password:
port:
{{#zipkinUri}}
zipkin:
base-url: {{zipkinUri}}
{{/zipkinUri}}
{{#springBootAdminUri}}
boot:
admin:
url: {{springBootAdminUri}}
client:
health-url: http://localhost:{{serverPort}}/health
management-url: http://localhost:{{serverPort}}
service-url: http://localhost:{{serverPort}}
{{/springBootAdminUri}}
sleuth:
sampler:
percentage: 1.0
logging:
level:
org:
springframework:
cloud:
sleuth: DEBUG

View File

@ -0,0 +1,87 @@
# Discovery Server Access
{{#eurekaUri}}
eureka:
instance:
leaseRenewalIntervalInSeconds: 1
leaseExpirationDurationInSeconds: 2
hostname: localhost
healthCheckUrl: http://localhost:{{serverPort}}/health
nonSecurePort: 80
client:
enabled: true
healthcheck:
enabled: true
registerWithEureka: true
#fetchRegistry: true
serviceUrl:
defaultZone: {{eurekaUri}}/eureka/
{{/eurekaUri}}
server:
port: {{serverPort}}
# Spring Actuator
management:
health:
redis:
enabled: false
security:
enabled: false
endpoints:
health:
sensitive: false
info:
app:
name: {{serviceName}}
description: Microservice developed by PKMST
version: {{artifactVersion}}
health:
hystrix:
enabled: true
security:
basic:
enabled: false
# provide rabbitmq configuration
spring:
rabbitmq:
host:
virtual-host:
username:
password:
port:
{{#zipkinUri}}
zipkin:
base-url: {{zipkinUri}}
{{/zipkinUri}}
{{#springBootAdminUri}}
boot:
admin:
url: {{springBootAdminUri}}
client:
health-url: http://localhost:{{serverPort}}/health
management-url: http://localhost:{{serverPort}}
service-url: http://localhost:{{serverPort}}
{{/springBootAdminUri}}
sleuth:
sampler:
percentage: 1.0
logging:
level:
org:
springframework:
cloud:
sleuth: DEBUG
{{#pkmstInterceptor}}
interceptor:
enable:
audit: true
body: true
rateLimit: true
traceability: true
correlation: true
{{/pkmstInterceptor}}

View File

@ -0,0 +1,5 @@
springfox.documentation.swagger.v2.path=/api-docs
server.contextPath={{^contextPath}}/{{/contextPath}}{{#contextPath}}{{contextPath}}{{/contextPath}}
server.port={{serverPort}}
spring.jackson.date-format={{basePackage}}.RFC3339DateFormat
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false

View File

@ -0,0 +1,5 @@
spring:
application:
name: {{artifactId}}
profiles:
active: local

View File

@ -0,0 +1 @@
{{#returnContainer}}{{#isMapContainer}}Map<String, {{{returnType}}}>{{/isMapContainer}}{{#isListContainer}}List<{{{returnType}}}>{{/isListContainer}}{{/returnContainer}}{{^returnContainer}}{{{returnType}}}{{/returnContainer}}

View File

@ -0,0 +1,61 @@
package {{basePackage}}.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;
/**
* Convenient strategy for configuring an OAUth2 Authorization Server. Beans of this type are applied to the Spring
* context automatically if you {@link EnableAuthorizationServer @EnableAuthorizationServer}.
*
* @author pkmst
*
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private static String REALM="MY_OAUTH_REALM";
@Autowired
private TokenStore tokenStore;
@Autowired
private UserApprovalHandler userApprovalHandler;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
.secret("secret")
.accessTokenValiditySeconds(120).//Access token is only valid for 2 minutes.
refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes.
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm(REALM+"/client");
}
}

View File

@ -0,0 +1,82 @@
package {{basePackage}}.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.core.annotation.Order;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
/**
* Provides a convenient base class for creating a {@link WebSecurityConfigurer}
* instance. The implementation allows customization by overriding methods.
*
* @see EnableWebSecurity
*
* @author pkmst
*/
@Configuration
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("admin@123").roles("ADMIN").and()
.withUser("user").password("user@123").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Bean
@Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
return handler;
}
@Bean
@Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}

View File

@ -0,0 +1,42 @@
package {{basePackage}}.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
import org.springframework.http.HttpMethod;
/**
* Configurer class for <code>@EnableResourceServer</code> classes. This class adjust the access
* rules and paths that are protected by OAuth2 security. If more than one configures the same property, then the last
* one wins. The configurers are sorted by {@link Order} before being applied.
*
* @author pkmst
*
*/
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "my_rest_api";
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
//configure security for the http methods
{{#resourcePaths}}
http.
anonymous().disable()
.requestMatchers().antMatchers(HttpMethod.GET, "/{{path}}/**")
.and().authorizeRequests()
.antMatchers(HttpMethod.GET, "/{{path}}/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
{{/resourcePaths}}
}
}

View File

@ -0,0 +1,4 @@
server.port = 8081
{{#eurekaUri}}
eureka.client.enabled=false
{{/eurekaUri}}

View File

@ -0,0 +1,4 @@
server.port = 8081
{{#eurekaUri}}
eureka.client.enabled=false
{{/eurekaUri}}

View File

@ -0,0 +1,5 @@
spring:
application:
name: {{artifactId}}
profiles:
active: test

View File

@ -0,0 +1,7 @@
{{#jackson}}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator}}", visible = true )
@JsonSubTypes({
{{#children}}
@JsonSubTypes.Type(value = {{classname}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"),
{{/children}}
}){{/jackson}}

View File

@ -0,0 +1,6 @@
{{#withXml}}
{{#jackson}}
@JacksonXmlRootElement({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{classname}}{{/xmlName}}")
{{/jackson}}
@XmlRootElement({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{classname}}{{/xmlName}}")
@XmlAccessorType(XmlAccessType.FIELD){{/withXml}}

View File

@ -844,6 +844,7 @@
<module>samples/client/petstore/go</module> <module>samples/client/petstore/go</module>
<!-- servers --> <!-- servers -->
<module>samples/server/petstore/java-inflector</module> <module>samples/server/petstore/java-inflector</module>
<module>samples/server/petstore/java-pkmst</module>
<module>samples/server/petstore/java-play-framework</module> <module>samples/server/petstore/java-play-framework</module>
<module>samples/server/petstore/undertow</module> <module>samples/server/petstore/undertow</module>
<module>samples/server/petstore/jaxrs/jersey1</module> <module>samples/server/petstore/jaxrs/jersey1</module>

View File

@ -0,0 +1,23 @@
# Swagger Codegen Ignore
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@ -0,0 +1 @@
2.3.0-SNAPSHOT

View File

@ -0,0 +1,3 @@
FROM frolvlad/alpine-oraclejdk8:slim
COPY target/pkmst-microservice.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

View File

@ -0,0 +1,142 @@
Dear Reader : Thanks for selecting PKMST swagger code generation toolkit for starting your microservice journey.
We believe the hard work we put into this framework will help you kick start your journey sooner and you will find it
easy to scale your service to enterprise grade. Another great thing is you don't need to enable all capabilities as you start,
but can enable as your microservice capabilities needs to be extended to meet strict enterprise standards.
PKMST feature set.
a)Read the Swagger supplied and will create a maven project
b)Create basic controller based on rest verb and path configured in swagger
c)generate default unit test cose using junit
d)generate all needed dependency needed to run the microservice on local
e)generate a default manifest file that allows you to push code to cloudfoundry instance ( eg pcf , ibm bluemix etc)
As you mature your knowledge with pkmst, you can leverage vendor extensions feature that will allow you to supply specific configuration
in your swagger and generate respective configuration that will
f)Allow you integrate with registry server (Example Eureka)
g)Allow you to integrate with tracing server (Example Zipkin)
h)Allow you to capture log in your microservice and send to Log management server (Ex ELK or splunk)
i)Allow you to configure Oauth2 security based authorization for your microservice
Additonal Features
j)generate sample cucumber file and dependency to drive your Behaviour driven development.
k)generate gatling based perfromance test , which can be excuted via build pipeline like jenkins etc.
Working:
Using swagger specification you can convert any definition to spring boot microservice.
It has the integration with the below services:
eureka registry, zipkin , spring boot admin, circuit breaker.
By default only the circuit breaker annotation is enabled. But one has to write the fallback method. The needed dependency for it is also been enabled. To generate the integration and
related configuration for eureka, zipkin, spring boot admin one has two options:
1) When generating from UI one has to provide vendor extensions inside the swagger specification as below:
swagger: "2.0"
info:
description: "This is a sample Product Catalogue Server.\
\ For this sample, you can use the api key `special-key` to test the authorization\
\ filters."
version: "1.0.0"
x-codegen:
eurekaUri: "http://localhost:8080"
zipkinUri: "http://localhost:9411"
springBootAdminUri: "http://localhost:8000"
pkmstInterceptor: "true"
PLease note the vendor extensions are inside the info tag of the swagger specification. All the tags are case sensitive. Once given all the related configuration and the dependency
will be enabled.
2) When generating from the maven plugin one has to provide configuration inside pom as below:
inside the swagger codegen maven plugin under the configuration section
<configuration>
<inputSpec>product-swagger.yaml</inputSpec>
<language>pkmst</language>
<output>${project.build.directory}/generated-sources</output>
<configOptions>
<groupId>com.prokarma</groupId>
<artifactId>product-catalogue</artifactId>
<artifactVersion>1.0</artifactVersion>
<basePackage>com.prokarma.pkmst</basePackage>
<serviceName>ProductCatalogue</serviceName>
<eurekaUri></eurekaUri>
<zipkinUri>http://localhost:9411</zipkinUri>
<springBootAdminUri>http://localhost:4588</springBootAdminUri>
<pkmstInterceptor>true</pkmstInterceptor>
</configOptions>
</configuration>
The project has three profiles local, dev, dev-config which can be configured accordingly. Once you have provided the uris you can see the necessary configurations generated inside the local and the dev
yml files. dev-config is for the config server if you want to use.(also enable the dependency for the config server inside the pom)
[Note: one has to run the zipkin, eureka, spring boot admin servers to be able to connect from the app. This project assumes that you have all the servers
up and running.]
Also provided are the middleware handlers:
1) traceInterceptor:is an id passed in from client and will be unique with an application context. The id will be passed into the backend and return to the consumer for transaction tracing.
2) correlationInterceptor:generates a UUID in the first API/service and pass it to all other APIs/services in the call tree for tracking purpose.
3) rateLimitInterceptor:is a rate limiting handler to limit number of concurrent requests on the server. Once the limit is reached, subsequent requests will be queued for later execution. The size of the queue is configurable.
4) auditInterceptor: audit logs most important info about request and response into audit.log in JSON format with config file that controls which fields to be logged
5) bodyInterceptor:s a body parser middleware that is responsible for parsing the content of the request based on Content-Type in the request header.
To be able to generate the handlers and the necessary configurations one has to provide the pkmstInterceptor key inside the vendor extensions or through
the maven plugin.
Once provided all the handlers are registered in the interceptor registry and can be enabled or disabled through the configuration provided inside
the application yml as below:
interceptor:
enable:
audit: true
body: true
rateLimit: true
traceability: true
correlation: true
For testing we have placeholders for junit test class, integration test class, cucumber sample
feature file(implement according to your needs), gatling load test.
Ways to run the project:
1) Normal spring boot application
2) Using Dockerfile to run in the container:
dockerfile will be generated inside the project by default. Image can be created using docker cli or through the maven plugin
<build>
<plugins>
...
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>VERSION GOES HERE</version>
<configuration>
<imageName>example</imageName>
<dockerDirectory>docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
...
</plugins>
</build>
Use manifest.yml file to push the application to the cloud.
HttpLogging filter is provided for logging in the request and response. Can be found inside the com.prokarma.pkmst.logging package.
Spring security is also provided to secure the resources. Please modify according to your needs.
First run:
Import the project in to the eclipse. Run the app as an spring boot application.The project will run on http://localhost:8008
Swagger ui available on:
http://localhost:8008/swagger-ui.html
If all the configurations have been enabled(depending on the port) below are some of the URls to access:
eureka: http://localhost:8080
zipkin: http://localhost:9411

View File

@ -0,0 +1,35 @@
input {
file {
path => ""
start_position => "beginning"
}
}
filter {
# pattern matching logback pattern
grok {
}
}
}
output {
# Print each event to stdout, useful for debugging. Should be commented out in production.
# Enabling 'rubydebug' codec on the stdout output will make logstash
# pretty-print the entire event as something similar to a JSON representation.
stdout {
codec => rubydebug
}
# Sending properly parsed log events to elasticsearch
elasticsearch {
hosts => ["localhost:9200"]
}
}

View File

@ -0,0 +1,12 @@
applications:
- name:
memory: 1G
instances: 1
host:
buildpack: https://github.com/cloudfoundry/java-buildpack.git
path:
services:
-
-
env:

View File

@ -0,0 +1,416 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.prokarma</groupId>
<artifactId>pkmst-microservice</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>pkmst-microservice</name>
<description>Demo project for Spring Boot Microservices</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>1.5.6.RELEASE</spring-boot.version>
<cucumber-junit.version>1.2.5</cucumber-junit.version>
<cucumber-java.version>1.2.5</cucumber-java.version>
<cucumber-reporting.version>3.10.0</cucumber-reporting.version>
<springfox-swagger2>2.6.1-SNAPSHOT</springfox-swagger2>
<springfox-swagger-ui>2.6.0</springfox-swagger-ui>
<slf4j-api>1.7.25</slf4j-api>
<logstash-logback-encoder>4.11</logstash-logback-encoder>
<logback-core>1.2.3</logback-core>
<logback-classic>1.2.3</logback-classic>
<gatling.version>2.3.0</gatling.version>
<gatling-plugin.version>2.2.4</gatling-plugin.version>
<scala-maven-plugin.version>3.2.2</scala-maven-plugin.version>
<spring-cloud.version>Camden.SR7</spring-cloud.version>
<spring-cloud-contract.version>1.1.3.RELEASE</spring-cloud-contract.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath />
<!-- lookup parent from repository -->
</parent>
<repositories>
<repository>
<id>oss-snapshots</id>
<name>JFrog OSS Snapshots</name>
<url>https://oss.jfrog.org/simple/oss-snapshot-local/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>central</id>
<name>Maven Repository Switchboard</name>
<layout>default</layout>
<url>http://repo1.maven.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
</dependency>
<!-- dependency for zipkin tracing with sleuth -->
<!-- if you only want sleuth -->
<!-- <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency> -->
<!-- Sleuth with Zipkin via Spring Cloud Stream -->
<!-- <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-stream</artifactId>
</dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency> -->
<!-- Spring Cloud Sleuth Stream Zipkin Collector -->
<!-- <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>
</dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency> -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!--<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- cucumber dependencies -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber-junit.version}</version>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber-java.version}</version>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-spring</artifactId>
<version>${cucumber-java.version}</version>
</dependency>
<dependency>
<groupId>net.masterthought</groupId>
<artifactId>cucumber-reporting</artifactId>
<version>${cucumber-reporting.version}</version>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>1.46</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-swagger2}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-swagger-ui}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api}</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>${logstash-logback-encoder}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-remote-shell</artifactId>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
<!--Gatling -->
<dependency>
<groupId>io.gatling.highcharts</groupId>
<artifactId>gatling-charts-highcharts</artifactId>
<version>${gatling.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>rest-assured</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.threeten</groupId>
<artifactId>threetenbp</artifactId>
<version>1.3.6</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludes>
<!-- classes that include the name CucumberTest, as an example -->
<exclude>**/*CucumberTest*.java</exclude>
<!-- classes in a package whose last segment is named cucumber, as
an example -->
<exclude>**/cucumber/*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>${scala-maven-plugin.version}</version>
</plugin>
<!--Enable for Gatling -->
<!-- <plugin>
<groupId>io.gatling</groupId>
<artifactId>gatling-maven-plugin</artifactId>
<version>${gatling-plugin.version}</version>
<configuration>
Run Multiple Simulations
<runMultipleSimulations>true</runMultipleSimulations>
<includes>
<simulationClass>testapi</simulationClass>
</includes>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<id>gatling</id>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
</plugin>-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<finalName>${project.name}</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<configuration>
<destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
<dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<reportPlugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
</plugin>
</reportPlugins>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>cucumber-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<!-- Include your Cucumber tests, as an example -->
<include>Test.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<versionRange>[1.0.1.RELEASE,)</versionRange>
<goals>
<goal>convert</goal>
<goal>generateTests</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -0,0 +1,30 @@
package com.prokarma.pkmst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* starts the spring boot application
* @author pkmst
*
*/
@SpringBootApplication
@EnableSwagger2
@EnableCircuitBreaker
@EnableHystrixDashboard
public class PkmstApplication {
private static final Logger LOGGER = LoggerFactory.getLogger(PkmstApplication.class);
public static void main(String[] args) {
LOGGER.debug("Running spring boot application");
SpringApplication.run(PkmstApplication.class, args);
}
}

View File

@ -0,0 +1,34 @@
package com.prokarma.pkmst.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Registers the interceptors which are configurable via yaml
* @author pkmst
*
*/
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
/**
* enabling cors support at global level which can be applied at various
* level also as below registry.addMapping("/api/**")
* .allowedOrigins("http://domain2.com") .allowedMethods("PUT", "DELETE")
* .allowedHeaders("header1", "header2", "header3")
* .exposedHeaders("header1", "header2")
* .allowCredentials(false).maxAge(3600);
*
* @return
*/
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
};
}
}

View File

@ -0,0 +1,113 @@
package com.prokarma.pkmst.config.swagger;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* Provides the swagger API info
* @author pkmst
*
*/
@Configuration
@ConfigurationProperties(prefix = "pkmst", ignoreUnknownFields = false)
public class PkmstProperties {
private final Swagger swagger = new Swagger();
public Swagger getSwagger() {
return swagger;
}
public static class Swagger {
private String title = "Pkmst API";
private String description = "Pkmst API documentation";
private String version = "0.0.1";
private String termsOfServiceUrl;
private String contactName;
private String contactUrl;
private String contactEmail;
private String license;
private String licenseUrl;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getTermsOfServiceUrl() {
return termsOfServiceUrl;
}
public void setTermsOfServiceUrl(String termsOfServiceUrl) {
this.termsOfServiceUrl = termsOfServiceUrl;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public String getContactUrl() {
return contactUrl;
}
public void setContactUrl(String contactUrl) {
this.contactUrl = contactUrl;
}
public String getContactEmail() {
return contactEmail;
}
public void setContactEmail(String contactEmail) {
this.contactEmail = contactEmail;
}
public String getLicense() {
return license;
}
public void setLicense(String license) {
this.license = license;
}
public String getLicenseUrl() {
return licenseUrl;
}
public void setLicenseUrl(String licenseUrl) {
this.licenseUrl = licenseUrl;
}
}
}

View File

@ -0,0 +1,61 @@
package com.prokarma.pkmst.config.swagger;
import java.util.Date;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StopWatch;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
//import static springfox.documentation.builders.PathSelectors.regex;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Enable swagger ui for application
* @author pkmst
*
*/
@EnableSwagger2
@Configuration
public class SwaggerDocumentationConfig {
public static final String DEFAULT_INCLUDE_PATTERN = "/pkmst/.*";
@Bean
public Docket swaggerSpringfoxDocket(PkmstProperties pkmstProperties) {
StopWatch watch = new StopWatch();
watch.start();
Contact contact = new Contact(
pkmstProperties.getSwagger().getContactName(),
pkmstProperties.getSwagger().getContactUrl(),
pkmstProperties.getSwagger().getContactEmail());
ApiInfo apiInfo = new ApiInfo(
pkmstProperties.getSwagger().getTitle(),
pkmstProperties.getSwagger().getDescription(),
pkmstProperties.getSwagger().getVersion(),
pkmstProperties.getSwagger().getTermsOfServiceUrl(),
contact,
pkmstProperties.getSwagger().getLicense(),
pkmstProperties.getSwagger().getLicenseUrl());
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo)
.forCodeGeneration(true)
.genericModelSubstitutes(ResponseEntity.class)
.ignoredParameterTypes(java.sql.Date.class)
.directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class)
.directModelSubstitute(java.time.ZonedDateTime.class, Date.class)
.directModelSubstitute(java.time.LocalDateTime.class, Date.class)
.select()
.apis(RequestHandlerSelectors.basePackage("com.prokarma.pkmst"))
// .paths(regex(DEFAULT_INCLUDE_PATTERN))
.paths(PathSelectors.any())
.build();
watch.stop();
return docket;
}
}

View File

@ -0,0 +1,153 @@
/**
* NOTE: This class is auto generated by the swagger code generator program (2.3.0-SNAPSHOT).
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
package com.prokarma.pkmst.controller;
import java.io.File;
import com.prokarma.pkmst.model.ModelApiResponse;
import com.prokarma.pkmst.model.Pet;
import io.swagger.annotations.*;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
/**
* Provides the info about api methods
* @author pkmst
*
*/
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
@Api(value = "Pet", description = "the Pet API")
public interface PetApi {
@ApiOperation(value = "Add a new pet to the store", notes = "", response = Void.class, authorizations = {
@Authorization(value = "petstore_auth", scopes = {
@AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
@AuthorizationScope(scope = "read:pets", description = "read your pets")
})
}, tags={ "pet", })
@ApiResponses(value = {
@ApiResponse(code = 405, message = "Invalid input") })
@RequestMapping(value = "/pet",
produces = { "application/xml", "application/json" },
consumes = { "application/json", "application/xml" },
method = RequestMethod.POST)
ResponseEntity<Void> addPet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @RequestBody Pet body, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Deletes a pet", notes = "", response = Void.class, authorizations = {
@Authorization(value = "petstore_auth", scopes = {
@AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
@AuthorizationScope(scope = "read:pets", description = "read your pets")
})
}, tags={ "pet", })
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid pet value") })
@RequestMapping(value = "/pet/{petId}",
produces = { "application/xml", "application/json" },
method = RequestMethod.DELETE)
ResponseEntity<Void> deletePet(@ApiParam(value = "Pet id to delete",required=true ) @PathVariable("petId") Long petId,@ApiParam(value = "" ) @RequestHeader(value="api_key", required=false) String apiKey, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Finds Pets by status", notes = "Multiple status values can be provided with comma separated strings", response = Pet.class, responseContainer = "List", authorizations = {
@Authorization(value = "petstore_auth", scopes = {
@AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
@AuthorizationScope(scope = "read:pets", description = "read your pets")
})
}, tags={ "pet", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Pet.class, responseContainer = "List"),
@ApiResponse(code = 400, message = "Invalid status value") })
@RequestMapping(value = "/pet/findByStatus",
produces = { "application/xml", "application/json" },
method = RequestMethod.GET)
ResponseEntity<List<Pet>> findPetsByStatus(@ApiParam(value = "Status values that need to be considered for filter", required = true, allowableValues = "available, pending, sold") @RequestParam(value = "status", required = true) List<String> status, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Finds Pets by tags", notes = "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", response = Pet.class, responseContainer = "List", authorizations = {
@Authorization(value = "petstore_auth", scopes = {
@AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
@AuthorizationScope(scope = "read:pets", description = "read your pets")
})
}, tags={ "pet", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Pet.class, responseContainer = "List"),
@ApiResponse(code = 400, message = "Invalid tag value") })
@RequestMapping(value = "/pet/findByTags",
produces = { "application/xml", "application/json" },
method = RequestMethod.GET)
ResponseEntity<List<Pet>> findPetsByTags(@ApiParam(value = "Tags to filter by", required = true) @RequestParam(value = "tags", required = true) List<String> tags, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Find pet by ID", notes = "Returns a single pet", response = Pet.class, authorizations = {
@Authorization(value = "api_key")
}, tags={ "pet", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Pet.class),
@ApiResponse(code = 400, message = "Invalid ID supplied"),
@ApiResponse(code = 404, message = "Pet not found") })
@RequestMapping(value = "/pet/{petId}",
produces = { "application/xml", "application/json" },
method = RequestMethod.GET)
ResponseEntity<Pet> getPetById(@ApiParam(value = "ID of pet to return",required=true ) @PathVariable("petId") Long petId, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Update an existing pet", notes = "", response = Void.class, authorizations = {
@Authorization(value = "petstore_auth", scopes = {
@AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
@AuthorizationScope(scope = "read:pets", description = "read your pets")
})
}, tags={ "pet", })
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid ID supplied"),
@ApiResponse(code = 404, message = "Pet not found"),
@ApiResponse(code = 405, message = "Validation exception") })
@RequestMapping(value = "/pet",
produces = { "application/xml", "application/json" },
consumes = { "application/json", "application/xml" },
method = RequestMethod.PUT)
ResponseEntity<Void> updatePet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @RequestBody Pet body, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Updates a pet in the store with form data", notes = "", response = Void.class, authorizations = {
@Authorization(value = "petstore_auth", scopes = {
@AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
@AuthorizationScope(scope = "read:pets", description = "read your pets")
})
}, tags={ "pet", })
@ApiResponses(value = {
@ApiResponse(code = 405, message = "Invalid input") })
@RequestMapping(value = "/pet/{petId}",
produces = { "application/xml", "application/json" },
consumes = { "application/x-www-form-urlencoded" },
method = RequestMethod.POST)
ResponseEntity<Void> updatePetWithForm(@ApiParam(value = "ID of pet that needs to be updated",required=true ) @PathVariable("petId") Long petId,@ApiParam(value = "Updated name of the pet") @RequestPart(value="name", required=false) String name,@ApiParam(value = "Updated status of the pet") @RequestPart(value="status", required=false) String status, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "uploads an image", notes = "", response = ModelApiResponse.class, authorizations = {
@Authorization(value = "petstore_auth", scopes = {
@AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
@AuthorizationScope(scope = "read:pets", description = "read your pets")
})
}, tags={ "pet", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = ModelApiResponse.class) })
@RequestMapping(value = "/pet/{petId}/uploadImage",
produces = { "application/json" },
consumes = { "multipart/form-data" },
method = RequestMethod.POST)
ResponseEntity<ModelApiResponse> uploadFile(@ApiParam(value = "ID of pet to update",required=true ) @PathVariable("petId") Long petId,@ApiParam(value = "Additional data to pass to server") @RequestPart(value="additionalMetadata", required=false) String additionalMetadata,@ApiParam(value = "file detail") @RequestPart("file") MultipartFile file, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
}

View File

@ -0,0 +1,126 @@
package com.prokarma.pkmst.controller;
import java.io.File;
import com.prokarma.pkmst.model.ModelApiResponse;
import com.prokarma.pkmst.model.Pet;
import io.swagger.annotations.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
/**
* Api implemention
* @author pkmst
*
*/
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
@Controller
public class PetApiController implements PetApi {
private final ObjectMapper objectMapper;
@Autowired
public PetApiController(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public ResponseEntity<Void> addPet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @RequestBody Pet body,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
return new ResponseEntity<Void>(HttpStatus.OK);
}
public ResponseEntity<Void> deletePet(@ApiParam(value = "Pet id to delete",required=true ) @PathVariable("petId") Long petId,
@ApiParam(value = "" ) @RequestHeader(value="api_key", required=false) String apiKey,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
return new ResponseEntity<Void>(HttpStatus.OK);
}
public ResponseEntity<List<Pet>> findPetsByStatus(@ApiParam(value = "Status values that need to be considered for filter", required = true, allowableValues = "available, pending, sold") @RequestParam(value = "status", required = true) List<String> status,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
if (accept != null && accept.contains("application/xml")) {
return new ResponseEntity<List<Pet>>(objectMapper.readValue("", List.class), HttpStatus.OK);
}
if (accept != null && accept.contains("application/json")) {
return new ResponseEntity<List<Pet>>(objectMapper.readValue("", List.class), HttpStatus.OK);
}
return new ResponseEntity<List<Pet>>(HttpStatus.OK);
}
public ResponseEntity<List<Pet>> findPetsByTags(@ApiParam(value = "Tags to filter by", required = true) @RequestParam(value = "tags", required = true) List<String> tags,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
if (accept != null && accept.contains("application/xml")) {
return new ResponseEntity<List<Pet>>(objectMapper.readValue("", List.class), HttpStatus.OK);
}
if (accept != null && accept.contains("application/json")) {
return new ResponseEntity<List<Pet>>(objectMapper.readValue("", List.class), HttpStatus.OK);
}
return new ResponseEntity<List<Pet>>(HttpStatus.OK);
}
public ResponseEntity<Pet> getPetById(@ApiParam(value = "ID of pet to return",required=true ) @PathVariable("petId") Long petId,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
if (accept != null && accept.contains("application/xml")) {
return new ResponseEntity<Pet>(objectMapper.readValue("", Pet.class), HttpStatus.OK);
}
if (accept != null && accept.contains("application/json")) {
return new ResponseEntity<Pet>(objectMapper.readValue("", Pet.class), HttpStatus.OK);
}
return new ResponseEntity<Pet>(HttpStatus.OK);
}
public ResponseEntity<Void> updatePet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @RequestBody Pet body,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
return new ResponseEntity<Void>(HttpStatus.OK);
}
public ResponseEntity<Void> updatePetWithForm(@ApiParam(value = "ID of pet that needs to be updated",required=true ) @PathVariable("petId") Long petId,
@ApiParam(value = "Updated name of the pet") @RequestPart(value="name", required=false) String name,
@ApiParam(value = "Updated status of the pet") @RequestPart(value="status", required=false) String status,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
return new ResponseEntity<Void>(HttpStatus.OK);
}
public ResponseEntity<ModelApiResponse> uploadFile(@ApiParam(value = "ID of pet to update",required=true ) @PathVariable("petId") Long petId,
@ApiParam(value = "Additional data to pass to server") @RequestPart(value="additionalMetadata", required=false) String additionalMetadata,
@ApiParam(value = "file detail") @RequestPart("file") MultipartFile file,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
if (accept != null && accept.contains("application/json")) {
return new ResponseEntity<ModelApiResponse>(objectMapper.readValue("", ModelApiResponse.class), HttpStatus.OK);
}
return new ResponseEntity<ModelApiResponse>(HttpStatus.OK);
}
}

View File

@ -0,0 +1,75 @@
/**
* NOTE: This class is auto generated by the swagger code generator program (2.3.0-SNAPSHOT).
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
package com.prokarma.pkmst.controller;
import java.util.Map;
import com.prokarma.pkmst.model.Order;
import io.swagger.annotations.*;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
/**
* Provides the info about api methods
* @author pkmst
*
*/
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
@Api(value = "Store", description = "the Store API")
public interface StoreApi {
@ApiOperation(value = "Delete purchase order by ID", notes = "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", response = Void.class, tags={ "store", })
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid ID supplied"),
@ApiResponse(code = 404, message = "Order not found") })
@RequestMapping(value = "/store/order/{orderId}",
produces = { "application/xml", "application/json" },
method = RequestMethod.DELETE)
ResponseEntity<Void> deleteOrder(@ApiParam(value = "ID of the order that needs to be deleted",required=true ) @PathVariable("orderId") String orderId, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Returns pet inventories by status", notes = "Returns a map of status codes to quantities", response = Integer.class, responseContainer = "Map", authorizations = {
@Authorization(value = "api_key")
}, tags={ "store", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Map.class, responseContainer = "Map") })
@RequestMapping(value = "/store/inventory",
produces = { "application/json" },
method = RequestMethod.GET)
ResponseEntity<Map<String, Integer>> getInventory( @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Find purchase order by ID", notes = "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", response = Order.class, tags={ "store", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Order.class),
@ApiResponse(code = 400, message = "Invalid ID supplied"),
@ApiResponse(code = 404, message = "Order not found") })
@RequestMapping(value = "/store/order/{orderId}",
produces = { "application/xml", "application/json" },
method = RequestMethod.GET)
ResponseEntity<Order> getOrderById(@ApiParam(value = "ID of pet that needs to be fetched",required=true ) @PathVariable("orderId") Long orderId, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Place an order for a pet", notes = "", response = Order.class, tags={ "store", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Order.class),
@ApiResponse(code = 400, message = "Invalid Order") })
@RequestMapping(value = "/store/order",
produces = { "application/xml", "application/json" },
method = RequestMethod.POST)
ResponseEntity<Order> placeOrder(@ApiParam(value = "order placed for purchasing the pet" ,required=true ) @RequestBody Order body, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
}

View File

@ -0,0 +1,85 @@
package com.prokarma.pkmst.controller;
import java.util.Map;
import com.prokarma.pkmst.model.Order;
import io.swagger.annotations.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
/**
* Api implemention
* @author pkmst
*
*/
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
@Controller
public class StoreApiController implements StoreApi {
private final ObjectMapper objectMapper;
@Autowired
public StoreApiController(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public ResponseEntity<Void> deleteOrder(@ApiParam(value = "ID of the order that needs to be deleted",required=true ) @PathVariable("orderId") String orderId,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
return new ResponseEntity<Void>(HttpStatus.OK);
}
public ResponseEntity<Map<String, Integer>> getInventory(@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
if (accept != null && accept.contains("application/json")) {
return new ResponseEntity<Map<String, Integer>>(objectMapper.readValue("", Map.class), HttpStatus.OK);
}
return new ResponseEntity<Map<String, Integer>>(HttpStatus.OK);
}
public ResponseEntity<Order> getOrderById(@ApiParam(value = "ID of pet that needs to be fetched",required=true ) @PathVariable("orderId") Long orderId,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
if (accept != null && accept.contains("application/xml")) {
return new ResponseEntity<Order>(objectMapper.readValue("", Order.class), HttpStatus.OK);
}
if (accept != null && accept.contains("application/json")) {
return new ResponseEntity<Order>(objectMapper.readValue("", Order.class), HttpStatus.OK);
}
return new ResponseEntity<Order>(HttpStatus.OK);
}
public ResponseEntity<Order> placeOrder(@ApiParam(value = "order placed for purchasing the pet" ,required=true ) @RequestBody Order body,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
if (accept != null && accept.contains("application/xml")) {
return new ResponseEntity<Order>(objectMapper.readValue("", Order.class), HttpStatus.OK);
}
if (accept != null && accept.contains("application/json")) {
return new ResponseEntity<Order>(objectMapper.readValue("", Order.class), HttpStatus.OK);
}
return new ResponseEntity<Order>(HttpStatus.OK);
}
}

View File

@ -0,0 +1,110 @@
/**
* NOTE: This class is auto generated by the swagger code generator program (2.3.0-SNAPSHOT).
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
package com.prokarma.pkmst.controller;
import java.util.List;
import com.prokarma.pkmst.model.User;
import io.swagger.annotations.*;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
/**
* Provides the info about api methods
* @author pkmst
*
*/
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
@Api(value = "User", description = "the User API")
public interface UserApi {
@ApiOperation(value = "Create user", notes = "This can only be done by the logged in user.", response = Void.class, tags={ "user", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation") })
@RequestMapping(value = "/user",
produces = { "application/xml", "application/json" },
method = RequestMethod.POST)
ResponseEntity<Void> createUser(@ApiParam(value = "Created user object" ,required=true ) @RequestBody User body, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Creates list of users with given input array", notes = "", response = Void.class, tags={ "user", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation") })
@RequestMapping(value = "/user/createWithArray",
produces = { "application/xml", "application/json" },
method = RequestMethod.POST)
ResponseEntity<Void> createUsersWithArrayInput(@ApiParam(value = "List of user object" ,required=true ) @RequestBody List<User> body, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Creates list of users with given input array", notes = "", response = Void.class, tags={ "user", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation") })
@RequestMapping(value = "/user/createWithList",
produces = { "application/xml", "application/json" },
method = RequestMethod.POST)
ResponseEntity<Void> createUsersWithListInput(@ApiParam(value = "List of user object" ,required=true ) @RequestBody List<User> body, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Delete user", notes = "This can only be done by the logged in user.", response = Void.class, tags={ "user", })
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid username supplied"),
@ApiResponse(code = 404, message = "User not found") })
@RequestMapping(value = "/user/{username}",
produces = { "application/xml", "application/json" },
method = RequestMethod.DELETE)
ResponseEntity<Void> deleteUser(@ApiParam(value = "The name that needs to be deleted",required=true ) @PathVariable("username") String username, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Get user by user name", notes = "", response = User.class, tags={ "user", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = User.class),
@ApiResponse(code = 400, message = "Invalid username supplied"),
@ApiResponse(code = 404, message = "User not found") })
@RequestMapping(value = "/user/{username}",
produces = { "application/xml", "application/json" },
method = RequestMethod.GET)
ResponseEntity<User> getUserByName(@ApiParam(value = "The name that needs to be fetched. Use user1 for testing. ",required=true ) @PathVariable("username") String username, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Logs user into the system", notes = "", response = String.class, tags={ "user", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = String.class),
@ApiResponse(code = 400, message = "Invalid username/password supplied") })
@RequestMapping(value = "/user/login",
produces = { "application/xml", "application/json" },
method = RequestMethod.GET)
ResponseEntity<String> loginUser(@ApiParam(value = "The user name for login", required = true) @RequestParam(value = "username", required = true) String username,@ApiParam(value = "The password for login in clear text", required = true) @RequestParam(value = "password", required = true) String password, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Logs out current logged in user session", notes = "", response = Void.class, tags={ "user", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation") })
@RequestMapping(value = "/user/logout",
produces = { "application/xml", "application/json" },
method = RequestMethod.GET)
ResponseEntity<Void> logoutUser( @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
@ApiOperation(value = "Updated user", notes = "This can only be done by the logged in user.", response = Void.class, tags={ "user", })
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid user supplied"),
@ApiResponse(code = 404, message = "User not found") })
@RequestMapping(value = "/user/{username}",
produces = { "application/xml", "application/json" },
method = RequestMethod.PUT)
ResponseEntity<Void> updateUser(@ApiParam(value = "name that need to be deleted",required=true ) @PathVariable("username") String username,@ApiParam(value = "Updated user object" ,required=true ) @RequestBody User body, @RequestHeader(value = "Accept", required = false) String accept) throws Exception;
}

View File

@ -0,0 +1,106 @@
package com.prokarma.pkmst.controller;
import java.util.List;
import com.prokarma.pkmst.model.User;
import io.swagger.annotations.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
/**
* Api implemention
* @author pkmst
*
*/
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
@Controller
public class UserApiController implements UserApi {
private final ObjectMapper objectMapper;
@Autowired
public UserApiController(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public ResponseEntity<Void> createUser(@ApiParam(value = "Created user object" ,required=true ) @RequestBody User body,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
return new ResponseEntity<Void>(HttpStatus.OK);
}
public ResponseEntity<Void> createUsersWithArrayInput(@ApiParam(value = "List of user object" ,required=true ) @RequestBody List<User> body,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
return new ResponseEntity<Void>(HttpStatus.OK);
}
public ResponseEntity<Void> createUsersWithListInput(@ApiParam(value = "List of user object" ,required=true ) @RequestBody List<User> body,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
return new ResponseEntity<Void>(HttpStatus.OK);
}
public ResponseEntity<Void> deleteUser(@ApiParam(value = "The name that needs to be deleted",required=true ) @PathVariable("username") String username,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
return new ResponseEntity<Void>(HttpStatus.OK);
}
public ResponseEntity<User> getUserByName(@ApiParam(value = "The name that needs to be fetched. Use user1 for testing. ",required=true ) @PathVariable("username") String username,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
if (accept != null && accept.contains("application/xml")) {
return new ResponseEntity<User>(objectMapper.readValue("", User.class), HttpStatus.OK);
}
if (accept != null && accept.contains("application/json")) {
return new ResponseEntity<User>(objectMapper.readValue("", User.class), HttpStatus.OK);
}
return new ResponseEntity<User>(HttpStatus.OK);
}
public ResponseEntity<String> loginUser(@ApiParam(value = "The user name for login", required = true) @RequestParam(value = "username", required = true) String username,
@ApiParam(value = "The password for login in clear text", required = true) @RequestParam(value = "password", required = true) String password,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
if (accept != null && accept.contains("application/xml")) {
return new ResponseEntity<String>(objectMapper.readValue("", String.class), HttpStatus.OK);
}
if (accept != null && accept.contains("application/json")) {
return new ResponseEntity<String>(objectMapper.readValue("", String.class), HttpStatus.OK);
}
return new ResponseEntity<String>(HttpStatus.OK);
}
public ResponseEntity<Void> logoutUser(@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
return new ResponseEntity<Void>(HttpStatus.OK);
}
public ResponseEntity<Void> updateUser(@ApiParam(value = "name that need to be deleted",required=true ) @PathVariable("username") String username,
@ApiParam(value = "Updated user object" ,required=true ) @RequestBody User body,
@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
return new ResponseEntity<Void>(HttpStatus.OK);
}
}

View File

@ -0,0 +1,434 @@
package com.prokarma.pkmst.logging;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.WriteListener;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.output.TeeOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* Implements javax.servlet.Filter and dump the request/response to syslog
* @author pkmst
*
*/
@Component
public class HttpLoggingFilter implements Filter {
private static final Logger log = LoggerFactory.getLogger(HttpLoggingFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
try {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
Map<String, String> requestMap = this.getTypesafeRequestMap(httpServletRequest);
BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpServletRequest);
BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(httpServletResponse);
final StringBuilder logMessage = new StringBuilder(
"REST Request - ").append("[HTTP METHOD:")
.append(httpServletRequest.getMethod())
.append("] [PATH INFO:")
.append(httpServletRequest.getServletPath())
.append("] [REQUEST PARAMETERS:").append(requestMap)
.append("] [REQUEST BODY:")
.append(bufferedRequest.getRequestBody())
.append("] [REMOTE ADDRESS:")
.append(httpServletRequest.getRemoteAddr()).append("]");
long start = System.currentTimeMillis();
chain.doFilter(bufferedRequest, bufferedResponse);
long elapsedTime = System.currentTimeMillis() - start;
String respContent = null;
if (bufferedResponse.getContent() == null || bufferedResponse.getContent() == "") {
respContent = "No data";
} else {
respContent = bufferedResponse.getContent();
}
logMessage.append(" [RESPONSE:").append(respContent)
.append("] [STATUS CODE:")
.append(bufferedResponse.getStatus())
.append("] [Response Time(ms):").append(elapsedTime)
.append("]");
log.info(logMessage.toString());
} catch (Throwable a) {
log.error(a.getMessage());
a.printStackTrace();
}
}
private Map<String, String> getTypesafeRequestMap(HttpServletRequest request) {
Map<String, String> typesafeRequestMap = new HashMap<String, String>();
Enumeration<?> requestParamNames = request.getParameterNames();
while (requestParamNames.hasMoreElements()) {
String requestParamName = (String) requestParamNames.nextElement();
String requestParamValue;
if (requestParamName.equalsIgnoreCase("password")) {
requestParamValue = "********";
} else {
requestParamValue = request.getParameter(requestParamName);
}
typesafeRequestMap.put(requestParamName, requestParamValue);
}
return typesafeRequestMap;
}
@Override
public void destroy() {
}
private static final class BufferedRequestWrapper extends HttpServletRequestWrapper {
private ByteArrayInputStream bais = null;
private ByteArrayOutputStream baos = null;
private BufferedServletInputStream bsis = null;
private byte[] buffer = null;
public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
super(req);
// Read InputStream and store its content in a buffer.
InputStream is = req.getInputStream();
this.baos = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int read;
while ((read = is.read(buf)) > 0) {
this.baos.write(buf, 0, read);
}
this.buffer = this.baos.toByteArray();
}
@Override
public ServletInputStream getInputStream() {
this.bais = new ByteArrayInputStream(this.buffer);
this.bsis = new BufferedServletInputStream(this.bais);
return this.bsis;
}
String getRequestBody() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(this.getInputStream()));
String line = null;
StringBuilder inputBuffer = new StringBuilder();
do {
line = reader.readLine();
if (null != line) {
inputBuffer.append(line.trim());
}
} while (line != null);
reader.close();
return inputBuffer.toString().trim();
}
}
private static final class BufferedServletInputStream extends ServletInputStream {
private ByteArrayInputStream bais;
public BufferedServletInputStream(ByteArrayInputStream bais) {
this.bais = bais;
}
@Override
public int available() {
return this.bais.available();
}
@Override
public int read() {
return this.bais.read();
}
@Override
public int read(byte[] buf, int off, int len) {
return this.bais.read(buf, off, len);
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
}
public class TeeServletOutputStream extends ServletOutputStream {
private final TeeOutputStream targetStream;
public TeeServletOutputStream(OutputStream one, OutputStream two) {
targetStream = new TeeOutputStream(one, two);
}
@Override
public void write(int arg0) throws IOException {
this.targetStream.write(arg0);
}
public void flush() throws IOException {
super.flush();
this.targetStream.flush();
}
public void close() throws IOException {
super.close();
this.targetStream.close();
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
}
public class BufferedResponseWrapper implements HttpServletResponse {
HttpServletResponse original;
TeeServletOutputStream tee;
ByteArrayOutputStream bos;
public BufferedResponseWrapper(HttpServletResponse response) {
original = response;
}
public String getContent() {
if (bos == null) {
return null;
} else
return bos.toString();
}
public PrintWriter getWriter() throws IOException {
return original.getWriter();
}
public ServletOutputStream getOutputStream() throws IOException {
if (tee == null) {
bos = new ByteArrayOutputStream();
tee = new TeeServletOutputStream(original.getOutputStream(),bos);
}
return tee;
}
@Override
public String getCharacterEncoding() {
return original.getCharacterEncoding();
}
@Override
public String getContentType() {
return original.getContentType();
}
@Override
public void setCharacterEncoding(String charset) {
original.setCharacterEncoding(charset);
}
@Override
public void setContentLength(int len) {
original.setContentLength(len);
}
@Override
public void setContentLengthLong(long l) {
original.setContentLengthLong(l);
}
@Override
public void setContentType(String type) {
original.setContentType(type);
}
@Override
public void setBufferSize(int size) {
original.setBufferSize(size);
}
@Override
public int getBufferSize() {
return original.getBufferSize();
}
@Override
public void flushBuffer() throws IOException {
tee.flush();
}
@Override
public void resetBuffer() {
original.resetBuffer();
}
@Override
public boolean isCommitted() {
return original.isCommitted();
}
@Override
public void reset() {
original.reset();
}
@Override
public void setLocale(Locale loc) {
original.setLocale(loc);
}
@Override
public Locale getLocale() {
return original.getLocale();
}
@Override
public void addCookie(Cookie cookie) {
original.addCookie(cookie);
}
@Override
public boolean containsHeader(String name) {
return original.containsHeader(name);
}
@Override
public String encodeURL(String url) {
return original.encodeURL(url);
}
@Override
public String encodeRedirectURL(String url) {
return original.encodeRedirectURL(url);
}
@SuppressWarnings("deprecation")
@Override
public String encodeUrl(String url) {
return original.encodeUrl(url);
}
@SuppressWarnings("deprecation")
@Override
public String encodeRedirectUrl(String url) {
return original.encodeRedirectUrl(url);
}
@Override
public void sendError(int sc, String msg) throws IOException {
original.sendError(sc, msg);
}
@Override
public void sendError(int sc) throws IOException {
original.sendError(sc);
}
@Override
public void sendRedirect(String location) throws IOException {
original.sendRedirect(location);
}
@Override
public void setDateHeader(String name, long date) {
original.setDateHeader(name, date);
}
@Override
public void addDateHeader(String name, long date) {
original.addDateHeader(name, date);
}
@Override
public void setHeader(String name, String value) {
original.setHeader(name, value);
}
@Override
public void addHeader(String name, String value) {
original.addHeader(name, value);
}
@Override
public void setIntHeader(String name, int value) {
original.setIntHeader(name, value);
}
@Override
public void addIntHeader(String name, int value) {
original.addIntHeader(name, value);
}
@Override
public void setStatus(int sc) {
original.setStatus(sc);
}
@SuppressWarnings("deprecation")
@Override
public void setStatus(int sc, String sm) {
original.setStatus(sc, sm);
}
@Override
public String getHeader(String arg0) {
return original.getHeader(arg0);
}
@Override
public Collection<String> getHeaderNames() {
return original.getHeaderNames();
}
@Override
public Collection<String> getHeaders(String arg0) {
return original.getHeaders(arg0);
}
@Override
public int getStatus() {
return original.getStatus();
}
}
}

View File

@ -0,0 +1,104 @@
package com.prokarma.pkmst.model;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* Response class to be returned by Api
* @author pkmst
*
*/
/**
* A category for a pet
*/
@ApiModel(description = "A category for a pet")
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
public class Category {
@JsonProperty("id")
private Long id = null;
@JsonProperty("name")
private String name = null;
public Category id(Long id) {
this.id = id;
return this;
}
/**
* Get id
* @return id
**/
@ApiModelProperty(value = "")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Category name(String name) {
this.name = name;
return this;
}
/**
* Get name
* @return name
**/
@ApiModelProperty(value = "")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Category category = (Category) o;
return Objects.equals(this.id, category.id) &&
Objects.equals(this.name, category.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Category {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" name: ").append(toIndentedString(name)).append("\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(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,127 @@
package com.prokarma.pkmst.model;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* Response class to be returned by Api
* @author pkmst
*
*/
/**
* Describes the result of uploading an image resource
*/
@ApiModel(description = "Describes the result of uploading an image resource")
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
public class ModelApiResponse {
@JsonProperty("code")
private Integer code = null;
@JsonProperty("type")
private String type = null;
@JsonProperty("message")
private String message = null;
public ModelApiResponse code(Integer code) {
this.code = code;
return this;
}
/**
* Get code
* @return code
**/
@ApiModelProperty(value = "")
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public ModelApiResponse type(String type) {
this.type = type;
return this;
}
/**
* Get type
* @return type
**/
@ApiModelProperty(value = "")
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public ModelApiResponse message(String message) {
this.message = message;
return this;
}
/**
* Get message
* @return message
**/
@ApiModelProperty(value = "")
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ModelApiResponse _apiResponse = (ModelApiResponse) o;
return Objects.equals(this.code, _apiResponse.code) &&
Objects.equals(this.type, _apiResponse.type) &&
Objects.equals(this.message, _apiResponse.message);
}
@Override
public int hashCode() {
return Objects.hash(code, type, message);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class ModelApiResponse {\n");
sb.append(" code: ").append(toIndentedString(code)).append("\n");
sb.append(" type: ").append(toIndentedString(type)).append("\n");
sb.append(" message: ").append(toIndentedString(message)).append("\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(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,231 @@
package com.prokarma.pkmst.model;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.threeten.bp.OffsetDateTime;
/**
* Response class to be returned by Api
* @author pkmst
*
*/
/**
* An order for a pets from the pet store
*/
@ApiModel(description = "An order for a pets from the pet store")
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
public class Order {
@JsonProperty("id")
private Long id = null;
@JsonProperty("petId")
private Long petId = null;
@JsonProperty("quantity")
private Integer quantity = null;
@JsonProperty("shipDate")
private OffsetDateTime shipDate = null;
/**
* Order Status
*/
public enum StatusEnum {
PLACED("placed"),
APPROVED("approved"),
DELIVERED("delivered");
private String value;
StatusEnum(String value) {
this.value = value;
}
@Override
@JsonValue
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static StatusEnum fromValue(String text) {
for (StatusEnum b : StatusEnum.values()) {
if (String.valueOf(b.value).equals(text)) {
return b;
}
}
return null;
}
}
@JsonProperty("status")
private StatusEnum status = null;
@JsonProperty("complete")
private Boolean complete = false;
public Order id(Long id) {
this.id = id;
return this;
}
/**
* Get id
* @return id
**/
@ApiModelProperty(value = "")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Order petId(Long petId) {
this.petId = petId;
return this;
}
/**
* Get petId
* @return petId
**/
@ApiModelProperty(value = "")
public Long getPetId() {
return petId;
}
public void setPetId(Long petId) {
this.petId = petId;
}
public Order quantity(Integer quantity) {
this.quantity = quantity;
return this;
}
/**
* Get quantity
* @return quantity
**/
@ApiModelProperty(value = "")
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public Order shipDate(OffsetDateTime shipDate) {
this.shipDate = shipDate;
return this;
}
/**
* Get shipDate
* @return shipDate
**/
@ApiModelProperty(value = "")
public OffsetDateTime getShipDate() {
return shipDate;
}
public void setShipDate(OffsetDateTime shipDate) {
this.shipDate = shipDate;
}
public Order status(StatusEnum status) {
this.status = status;
return this;
}
/**
* Order Status
* @return status
**/
@ApiModelProperty(value = "Order Status")
public StatusEnum getStatus() {
return status;
}
public void setStatus(StatusEnum status) {
this.status = status;
}
public Order complete(Boolean complete) {
this.complete = complete;
return this;
}
/**
* Get complete
* @return complete
**/
@ApiModelProperty(value = "")
public Boolean isComplete() {
return complete;
}
public void setComplete(Boolean complete) {
this.complete = complete;
}
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Order order = (Order) o;
return Objects.equals(this.id, order.id) &&
Objects.equals(this.petId, order.petId) &&
Objects.equals(this.quantity, order.quantity) &&
Objects.equals(this.shipDate, order.shipDate) &&
Objects.equals(this.status, order.status) &&
Objects.equals(this.complete, order.complete);
}
@Override
public int hashCode() {
return Objects.hash(id, petId, quantity, shipDate, status, complete);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Order {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" petId: ").append(toIndentedString(petId)).append("\n");
sb.append(" quantity: ").append(toIndentedString(quantity)).append("\n");
sb.append(" shipDate: ").append(toIndentedString(shipDate)).append("\n");
sb.append(" status: ").append(toIndentedString(status)).append("\n");
sb.append(" complete: ").append(toIndentedString(complete)).append("\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(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,249 @@
package com.prokarma.pkmst.model;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.prokarma.pkmst.model.Category;
import com.prokarma.pkmst.model.Tag;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.ArrayList;
import java.util.List;
/**
* Response class to be returned by Api
* @author pkmst
*
*/
/**
* A pet for sale in the pet store
*/
@ApiModel(description = "A pet for sale in the pet store")
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
public class Pet {
@JsonProperty("id")
private Long id = null;
@JsonProperty("category")
private Category category = null;
@JsonProperty("name")
private String name = null;
@JsonProperty("photoUrls")
private List<String> photoUrls = new ArrayList<>();
@JsonProperty("tags")
private List<Tag> tags = null;
/**
* pet status in the store
*/
public enum StatusEnum {
AVAILABLE("available"),
PENDING("pending"),
SOLD("sold");
private String value;
StatusEnum(String value) {
this.value = value;
}
@Override
@JsonValue
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static StatusEnum fromValue(String text) {
for (StatusEnum b : StatusEnum.values()) {
if (String.valueOf(b.value).equals(text)) {
return b;
}
}
return null;
}
}
@JsonProperty("status")
private StatusEnum status = null;
public Pet id(Long id) {
this.id = id;
return this;
}
/**
* Get id
* @return id
**/
@ApiModelProperty(value = "")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Pet category(Category category) {
this.category = category;
return this;
}
/**
* Get category
* @return category
**/
@ApiModelProperty(value = "")
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public Pet name(String name) {
this.name = name;
return this;
}
/**
* Get name
* @return name
**/
@ApiModelProperty(example = "doggie", required = true, value = "")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Pet photoUrls(List<String> photoUrls) {
this.photoUrls = photoUrls;
return this;
}
public Pet addPhotoUrlsItem(String photoUrlsItem) {
this.photoUrls.add(photoUrlsItem);
return this;
}
/**
* Get photoUrls
* @return photoUrls
**/
@ApiModelProperty(required = true, value = "")
public List<String> getPhotoUrls() {
return photoUrls;
}
public void setPhotoUrls(List<String> photoUrls) {
this.photoUrls = photoUrls;
}
public Pet tags(List<Tag> tags) {
this.tags = tags;
return this;
}
public Pet addTagsItem(Tag tagsItem) {
if (this.tags == null) {
this.tags = new ArrayList<>();
}
this.tags.add(tagsItem);
return this;
}
/**
* Get tags
* @return tags
**/
@ApiModelProperty(value = "")
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
public Pet status(StatusEnum status) {
this.status = status;
return this;
}
/**
* pet status in the store
* @return status
**/
@ApiModelProperty(value = "pet status in the store")
public StatusEnum getStatus() {
return status;
}
public void setStatus(StatusEnum status) {
this.status = status;
}
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Pet pet = (Pet) o;
return Objects.equals(this.id, pet.id) &&
Objects.equals(this.category, pet.category) &&
Objects.equals(this.name, pet.name) &&
Objects.equals(this.photoUrls, pet.photoUrls) &&
Objects.equals(this.tags, pet.tags) &&
Objects.equals(this.status, pet.status);
}
@Override
public int hashCode() {
return Objects.hash(id, category, name, photoUrls, tags, status);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Pet {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" category: ").append(toIndentedString(category)).append("\n");
sb.append(" name: ").append(toIndentedString(name)).append("\n");
sb.append(" photoUrls: ").append(toIndentedString(photoUrls)).append("\n");
sb.append(" tags: ").append(toIndentedString(tags)).append("\n");
sb.append(" status: ").append(toIndentedString(status)).append("\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(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,104 @@
package com.prokarma.pkmst.model;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* Response class to be returned by Api
* @author pkmst
*
*/
/**
* A tag for a pet
*/
@ApiModel(description = "A tag for a pet")
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
public class Tag {
@JsonProperty("id")
private Long id = null;
@JsonProperty("name")
private String name = null;
public Tag id(Long id) {
this.id = id;
return this;
}
/**
* Get id
* @return id
**/
@ApiModelProperty(value = "")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Tag name(String name) {
this.name = name;
return this;
}
/**
* Get name
* @return name
**/
@ApiModelProperty(value = "")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Tag tag = (Tag) o;
return Objects.equals(this.id, tag.id) &&
Objects.equals(this.name, tag.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Tag {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" name: ").append(toIndentedString(name)).append("\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(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,242 @@
package com.prokarma.pkmst.model;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* Response class to be returned by Api
* @author pkmst
*
*/
/**
* A User who is purchasing from the pet store
*/
@ApiModel(description = "A User who is purchasing from the pet store")
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaPKMSTServerCodegen", date = "2017-12-18T14:05:35.281+05:30")
public class User {
@JsonProperty("id")
private Long id = null;
@JsonProperty("username")
private String username = null;
@JsonProperty("firstName")
private String firstName = null;
@JsonProperty("lastName")
private String lastName = null;
@JsonProperty("email")
private String email = null;
@JsonProperty("password")
private String password = null;
@JsonProperty("phone")
private String phone = null;
@JsonProperty("userStatus")
private Integer userStatus = null;
public User id(Long id) {
this.id = id;
return this;
}
/**
* Get id
* @return id
**/
@ApiModelProperty(value = "")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public User username(String username) {
this.username = username;
return this;
}
/**
* Get username
* @return username
**/
@ApiModelProperty(value = "")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public User firstName(String firstName) {
this.firstName = firstName;
return this;
}
/**
* Get firstName
* @return firstName
**/
@ApiModelProperty(value = "")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public User lastName(String lastName) {
this.lastName = lastName;
return this;
}
/**
* Get lastName
* @return lastName
**/
@ApiModelProperty(value = "")
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public User email(String email) {
this.email = email;
return this;
}
/**
* Get email
* @return email
**/
@ApiModelProperty(value = "")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public User password(String password) {
this.password = password;
return this;
}
/**
* Get password
* @return password
**/
@ApiModelProperty(value = "")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User phone(String phone) {
this.phone = phone;
return this;
}
/**
* Get phone
* @return phone
**/
@ApiModelProperty(value = "")
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public User userStatus(Integer userStatus) {
this.userStatus = userStatus;
return this;
}
/**
* User Status
* @return userStatus
**/
@ApiModelProperty(value = "User Status")
public Integer getUserStatus() {
return userStatus;
}
public void setUserStatus(Integer userStatus) {
this.userStatus = userStatus;
}
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
User user = (User) o;
return Objects.equals(this.id, user.id) &&
Objects.equals(this.username, user.username) &&
Objects.equals(this.firstName, user.firstName) &&
Objects.equals(this.lastName, user.lastName) &&
Objects.equals(this.email, user.email) &&
Objects.equals(this.password, user.password) &&
Objects.equals(this.phone, user.phone) &&
Objects.equals(this.userStatus, user.userStatus);
}
@Override
public int hashCode() {
return Objects.hash(id, username, firstName, lastName, email, password, phone, userStatus);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class User {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" username: ").append(toIndentedString(username)).append("\n");
sb.append(" firstName: ").append(toIndentedString(firstName)).append("\n");
sb.append(" lastName: ").append(toIndentedString(lastName)).append("\n");
sb.append(" email: ").append(toIndentedString(email)).append("\n");
sb.append(" password: ").append(toIndentedString(password)).append("\n");
sb.append(" phone: ").append(toIndentedString(phone)).append("\n");
sb.append(" userStatus: ").append(toIndentedString(userStatus)).append("\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(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,61 @@
package com.prokarma.pkmst.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;
/**
* Convenient strategy for configuring an OAUth2 Authorization Server. Beans of this type are applied to the Spring
* context automatically if you {@link EnableAuthorizationServer @EnableAuthorizationServer}.
*
* @author pkmst
*
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private static String REALM="MY_OAUTH_REALM";
@Autowired
private TokenStore tokenStore;
@Autowired
private UserApprovalHandler userApprovalHandler;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
.secret("secret")
.accessTokenValiditySeconds(120).//Access token is only valid for 2 minutes.
refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes.
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm(REALM+"/client");
}
}

View File

@ -0,0 +1,82 @@
package com.prokarma.pkmst.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.core.annotation.Order;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
/**
* Provides a convenient base class for creating a {@link WebSecurityConfigurer}
* instance. The implementation allows customization by overriding methods.
*
* @see EnableWebSecurity
*
* @author pkmst
*/
@Configuration
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("admin@123").roles("ADMIN").and()
.withUser("user").password("user@123").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Bean
@Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
return handler;
}
@Bean
@Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}

View File

@ -0,0 +1,52 @@
package com.prokarma.pkmst.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
import org.springframework.http.HttpMethod;
/**
* Configurer class for <code>@EnableResourceServer</code> classes. This class adjust the access
* rules and paths that are protected by OAuth2 security. If more than one configures the same property, then the last
* one wins. The configurers are sorted by {@link Order} before being applied.
*
* @author pkmst
*
*/
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "my_rest_api";
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
//configure security for the http methods
http.
anonymous().disable()
.requestMatchers().antMatchers(HttpMethod.GET, "/pet/**")
.and().authorizeRequests()
.antMatchers(HttpMethod.GET, "/pet/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
http.
anonymous().disable()
.requestMatchers().antMatchers(HttpMethod.GET, "/store/**")
.and().authorizeRequests()
.antMatchers(HttpMethod.GET, "/store/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
http.
anonymous().disable()
.requestMatchers().antMatchers(HttpMethod.GET, "/user/**")
.and().authorizeRequests()
.antMatchers(HttpMethod.GET, "/user/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}

View File

@ -0,0 +1,7 @@
#Enable cloud config. Also enable the dependency in pom
#cloud:
#config:
#uri:
#fail-fast: true
#password: user
#username: user

View File

@ -0,0 +1,48 @@
# Discovery Server Access
server:
port: 8008
# Spring Actuator
management:
health:
redis:
enabled: false
security:
enabled: false
endpoints:
health:
sensitive: false
info:
app:
name: Pkmst
description: Microservice developed by PKMST
version: 1.0.0
health:
hystrix:
enabled: true
security:
basic:
enabled: false
# provide rabbitmq configuration
spring:
rabbitmq:
host:
virtual-host:
username:
password:
port:
sleuth:
sampler:
percentage: 1.0
logging:
level:
org:
springframework:
cloud:
sleuth: DEBUG

View File

@ -0,0 +1,49 @@
# Discovery Server Access
server:
port: 8008
# Spring Actuator
management:
health:
redis:
enabled: false
security:
enabled: false
endpoints:
health:
sensitive: false
info:
app:
name: Pkmst
description: Microservice developed by PKMST
version: 1.0.0
health:
hystrix:
enabled: true
security:
basic:
enabled: false
# provide rabbitmq configuration
spring:
rabbitmq:
host:
virtual-host:
username:
password:
port:
sleuth:
sampler:
percentage: 1.0
logging:
level:
org:
springframework:
cloud:
sleuth: DEBUG

View File

@ -0,0 +1,5 @@
spring:
application:
name: pkmst-microservice
profiles:
active: local

View File

@ -0,0 +1,177 @@
/*
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
package com.prokarma.pkmst.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import com.prokarma.pkmst.model.ModelApiResponse;
import com.prokarma.pkmst.model.Pet;
import org.junit.Test;
import org.junit.Ignore;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
/**
* API tests for PetApi
*/
@Ignore
public class PetApiTest {
private final ObjectMapper objectMapper = new ObjectMapper();
private final PetApi api = new PetApiController(objectMapper);
private final String accept = "application/json";
/**
* Add a new pet to the store
*
*
*
* @throws Exception
* if the Api call fails
*/
@Test
public void addPetTest() throws Exception {
Pet body = null;
ResponseEntity<Void> response = api.addPet(body , accept);
// TODO: test validations
}
/**
* Deletes a pet
*
*
*
* @throws Exception
* if the Api call fails
*/
@Test
public void deletePetTest() throws Exception {
Long petId = null;
String apiKey = null;
ResponseEntity<Void> response = api.deletePet(petId, apiKey , accept);
// TODO: test validations
}
/**
* Finds Pets by status
*
* Multiple status values can be provided with comma separated strings
*
* @throws Exception
* if the Api call fails
*/
@Test
public void findPetsByStatusTest() throws Exception {
List<String> status = null;
ResponseEntity<List<Pet>> response = api.findPetsByStatus(status , accept);
// TODO: test validations
}
/**
* Finds Pets by tags
*
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
*
* @throws Exception
* if the Api call fails
*/
@Test
public void findPetsByTagsTest() throws Exception {
List<String> tags = null;
ResponseEntity<List<Pet>> response = api.findPetsByTags(tags , accept);
// TODO: test validations
}
/**
* Find pet by ID
*
* Returns a single pet
*
* @throws Exception
* if the Api call fails
*/
@Test
public void getPetByIdTest() throws Exception {
Long petId = null;
ResponseEntity<Pet> response = api.getPetById(petId , accept);
// TODO: test validations
}
/**
* Update an existing pet
*
*
*
* @throws Exception
* if the Api call fails
*/
@Test
public void updatePetTest() throws Exception {
Pet body = null;
ResponseEntity<Void> response = api.updatePet(body , accept);
// TODO: test validations
}
/**
* Updates a pet in the store with form data
*
*
*
* @throws Exception
* if the Api call fails
*/
@Test
public void updatePetWithFormTest() throws Exception {
Long petId = null;
String name = null;
String status = null;
ResponseEntity<Void> response = api.updatePetWithForm(petId, name, status , accept);
// TODO: test validations
}
/**
* uploads an image
*
*
*
* @throws Exception
* if the Api call fails
*/
@Test
public void uploadFileTest() throws Exception {
Long petId = null;
String additionalMetadata = null;
MultipartFile file = null;
ResponseEntity<ModelApiResponse> response = api.uploadFile(petId, additionalMetadata, file , accept);
// TODO: test validations
}
}

View File

@ -0,0 +1,34 @@
package com.prokarma.pkmst.controller;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import com.prokarma.pkmst.PkmstApplication;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = PkmstApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PkmstIT {
@LocalServerPort
private int port;
TestRestTemplate restTemplate = new TestRestTemplate();
HttpHeaders headers = new HttpHeaders();
@Test
public void testYourMethod() {
//add your logic
}
private String createURLWithPort(String uri) {
return "http://localhost:" + port + uri;
}
}

View File

@ -0,0 +1,106 @@
/*
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
package com.prokarma.pkmst.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import com.prokarma.pkmst.model.Order;
import org.junit.Test;
import org.junit.Ignore;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
/**
* API tests for StoreApi
*/
@Ignore
public class StoreApiTest {
private final ObjectMapper objectMapper = new ObjectMapper();
private final StoreApi api = new StoreApiController(objectMapper);
private final String accept = "application/json";
/**
* Delete purchase order by ID
*
* For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
*
* @throws Exception
* if the Api call fails
*/
@Test
public void deleteOrderTest() throws Exception {
String orderId = null;
ResponseEntity<Void> response = api.deleteOrder(orderId , accept);
// TODO: test validations
}
/**
* Returns pet inventories by status
*
* Returns a map of status codes to quantities
*
* @throws Exception
* if the Api call fails
*/
@Test
public void getInventoryTest() throws Exception {
ResponseEntity<Map<String, Integer>> response = api.getInventory( accept);
// TODO: test validations
}
/**
* Find purchase order by ID
*
* For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions
*
* @throws Exception
* if the Api call fails
*/
@Test
public void getOrderByIdTest() throws Exception {
Long orderId = null;
ResponseEntity<Order> response = api.getOrderById(orderId , accept);
// TODO: test validations
}
/**
* Place an order for a pet
*
*
*
* @throws Exception
* if the Api call fails
*/
@Test
public void placeOrderTest() throws Exception {
Order body = null;
ResponseEntity<Order> response = api.placeOrder(body , accept);
// TODO: test validations
}
}

View File

@ -0,0 +1,172 @@
/*
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
package com.prokarma.pkmst.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import com.prokarma.pkmst.model.User;
import org.junit.Test;
import org.junit.Ignore;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
/**
* API tests for UserApi
*/
@Ignore
public class UserApiTest {
private final ObjectMapper objectMapper = new ObjectMapper();
private final UserApi api = new UserApiController(objectMapper);
private final String accept = "application/json";
/**
* Create user
*
* This can only be done by the logged in user.
*
* @throws Exception
* if the Api call fails
*/
@Test
public void createUserTest() throws Exception {
User body = null;
ResponseEntity<Void> response = api.createUser(body , accept);
// TODO: test validations
}
/**
* Creates list of users with given input array
*
*
*
* @throws Exception
* if the Api call fails
*/
@Test
public void createUsersWithArrayInputTest() throws Exception {
List<User> body = null;
ResponseEntity<Void> response = api.createUsersWithArrayInput(body , accept);
// TODO: test validations
}
/**
* Creates list of users with given input array
*
*
*
* @throws Exception
* if the Api call fails
*/
@Test
public void createUsersWithListInputTest() throws Exception {
List<User> body = null;
ResponseEntity<Void> response = api.createUsersWithListInput(body , accept);
// TODO: test validations
}
/**
* Delete user
*
* This can only be done by the logged in user.
*
* @throws Exception
* if the Api call fails
*/
@Test
public void deleteUserTest() throws Exception {
String username = null;
ResponseEntity<Void> response = api.deleteUser(username , accept);
// TODO: test validations
}
/**
* Get user by user name
*
*
*
* @throws Exception
* if the Api call fails
*/
@Test
public void getUserByNameTest() throws Exception {
String username = null;
ResponseEntity<User> response = api.getUserByName(username , accept);
// TODO: test validations
}
/**
* Logs user into the system
*
*
*
* @throws Exception
* if the Api call fails
*/
@Test
public void loginUserTest() throws Exception {
String username = null;
String password = null;
ResponseEntity<String> response = api.loginUser(username, password , accept);
// TODO: test validations
}
/**
* Logs out current logged in user session
*
*
*
* @throws Exception
* if the Api call fails
*/
@Test
public void logoutUserTest() throws Exception {
ResponseEntity<Void> response = api.logoutUser( accept);
// TODO: test validations
}
/**
* Updated user
*
* This can only be done by the logged in user.
*
* @throws Exception
* if the Api call fails
*/
@Test
public void updateUserTest() throws Exception {
String username = null;
User body = null;
ResponseEntity<Void> response = api.updateUser(username, body , accept);
// TODO: test validations
}
}

View File

@ -0,0 +1,76 @@
package com.prokarma.pkmst.cucumber;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import cucumber.api.PendingException;
public class PkmstSteps {
@Given("^I want to write a step with precondition$")
public void i_want_to_write_a_step_with_precondition() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Given("^some other precondition$")
public void some_other_precondition() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@When("^I complete action$")
public void i_complete_action() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@When("^some other action$")
public void some_other_action() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@When("^yet another action$")
public void yet_another_action() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Then("^I validate the outcomes$")
public void i_validate_the_outcomes() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Then("^check more outcomes$")
public void check_more_outcomes() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Given("^I want to write a step with name(\\d+)$")
public void i_want_to_write_a_step_with_name(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@When("^I check for the (\\d+) in step$")
public void i_check_for_the_in_step(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Then("^I verify the success in step$")
public void i_verify_the_success_in_step() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Then("^I verify the Fail in step$")
public void i_verify_the_Fail_in_step() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
}

View File

@ -0,0 +1,16 @@
package com.prokarma.pkmst.cucumber;
import org.junit.runner.RunWith;
import org.springframework.test.context.ActiveProfiles;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
@RunWith(Cucumber.class)
@ActiveProfiles("test")
@CucumberOptions(format = { "pretty", "html:target/cucumber-html-report",
"json:./report/pet-report-json/pet.json",
"json:./report/store-report-json/store.json",
"json:./report/user-report-json/user.json",
})
public class PkmstTest {
}

View File

@ -0,0 +1,2 @@
package com.prokarma.pkmst.cucumber;
//Implement the feature file steps in this package.

Some files were not shown because too many files have changed in this diff Show More