Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tempproject #49

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ hs_err_pid*
/build
/.idea/
/generated/

*.DS_Store
135 changes: 135 additions & 0 deletions JsonSchemaValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import org.everit.json.schema.Schema;
import org.everit.json.schema.ValidationException;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class JsonSchemaValidator {

private static final String DEFAULT_SCHEMA_PATH = "schema.json";
private static final String SCHEMA_ENV_VAR = "JSON_SCHEMA_PATH";
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage: java JsonSchemaValidator <json_file>");
System.exit(1);
}

String jsonPath = args[0];
String schemaPath = System.getenv(SCHEMA_ENV_VAR);
if (schemaPath == null || schemaPath.isEmpty()) {
schemaPath = DEFAULT_SCHEMA_PATH;
System.out.println("Warning: JSON_SCHEMA_PATH not set. Using default schema path: " + DEFAULT_SCHEMA_PATH);
}

try {
String jsonContent = new String(Files.readAllBytes(Paths.get(jsonPath)));
JSONObject jsonSchema = new JSONObject(new JSONTokener(new FileInputStream(schemaPath)));
JSONObject jsonSubject = new JSONObject(jsonContent);

Schema schema = SchemaLoader.load(jsonSchema);
schema.validate(jsonSubject);

System.out.println("Validation successful! The JSON is valid against the schema.");

} catch (ValidationException ve) {
System.out.println("JSON validation failed. Errors:");
printValidationErrors(ve, jsonPath);
} catch (JSONException je) {
System.out.println("JSON parsing error:");
printJSONParsingError(je, jsonPath);
} catch (IOException e) {
System.out.println("Error reading files: " + e.getMessage());
}
}

private static void printValidationErrors(ValidationException ve, String jsonPath) {
List<String> allMessages = ve.getAllMessages();
for (int i = 0; i < allMessages.size(); i++) {
System.out.printf("%d. %s%n", i + 1, allMessages.get(i));
}
System.out.println("\nDetailed error information:");
printValidationErrorDetails(ve, jsonPath, 0);
}

private static void printValidationErrorDetails(ValidationException ve, String jsonPath, int depth) {
String indent = " ".repeat(depth);
System.out.printf("%sError: %s%n", indent, ve.getMessage());
System.out.printf("%sJSON Path: %s%n", indent, ve.getPointerToViolation());

try {
List<String> lines = Files.readAllLines(Paths.get(jsonPath));
String errorPath = ve.getPointerToViolation();
int lineNumber = findLineNumber(lines, errorPath);
if (lineNumber != -1) {
System.out.printf("%sLine number: %d%n", indent, lineNumber);
System.out.printf("%sLine content: %s%n", indent, lines.get(lineNumber - 1).trim());
}
} catch (IOException e) {
System.out.printf("%sUnable to retrieve line information: %s%n", indent, e.getMessage());
}

List<ValidationException> causingExceptions = ve.getCausingExceptions();
if (!causingExceptions.isEmpty()) {
System.out.printf("%sNested errors:%n", indent);
for (ValidationException cause : causingExceptions) {
printValidationErrorDetails(cause, jsonPath, depth + 1);
}
}
}

private static void printJSONParsingError(JSONException je, String jsonPath) {
System.out.println(je.getMessage());

try {
List<String> lines = Files.readAllLines(Paths.get(jsonPath));
if (je.getMessage().contains("at character")) {
int charPosition = Integer.parseInt(je.getMessage().replaceAll(".*at character (\\d+).*", "$1"));
int lineNumber = 1;
int currentPosition = 0;

for (String line : lines) {
if (currentPosition + line.length() + 1 > charPosition) {
System.out.printf("Line number: %d%n", lineNumber);
System.out.printf("Line content: %s%n", line.trim());
System.out.printf("Error position: %s^%n", " ".repeat(charPosition - currentPosition - 1));
break;
}
currentPosition += line.length() + 1; // +1 for newline
lineNumber++;
}
}
} catch (IOException e) {
System.out.println("Unable to retrieve line information: " + e.getMessage());
}
}

private static int findLineNumber(List<String> lines, String jsonPath) {
String[] pathParts = jsonPath.split("/");
StringBuilder currentPath = new StringBuilder();
int nestingLevel = 0;

for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i).trim();
if (line.contains(":")) {
String key = line.split(":")[0].trim().replace("\"", "");
if (nestingLevel < pathParts.length && key.equals(pathParts[nestingLevel])) {
currentPath.append("/").append(key);
nestingLevel++;
if (currentPath.toString().equals(jsonPath)) {
return i + 1; // +1 because line numbers start at 1
}
}
}
if (line.contains("{")) nestingLevel++;
if (line.contains("}")) nestingLevel--;
}
return -1; // Path not found
}
}
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,27 @@ public class Example {
Tax provider capabilities for new tax providers will be validated against a constantly updating JSON Schema, to validate the correctness and completeness of configurations. JSON Schema can be referenced below.
- [TaxProviderCapabilities JSONSchema](spec/capabilities/tax-provider.schema.json)

Prerequisites:
Use Java8 or higher version.

1. Clone repository in local
```shell
git clone git@github.com:chargebee/cb-provider-spi.git
```

2. Navigate to the repository
```shell
cd cb-provider-spi
```
3. Run the script to perform json schema validation:
```shell
./json_schema_validation.sh <path to json file>
```
Example:
```shell
./json_schema_validation.sh spec/capabilities/tax-provider.file.json
```

## Steps to follow release


Expand All @@ -128,3 +149,32 @@ Tax provider capabilities for new tax providers will be validated against a cons
6. After PR is approved and merged
7. Raise PR from release/0.0.9 to dev. Once PR is merged it will auto release the 0.0.9 version of SPI for dev code base
8. After that raise PR from release/0.0.9 to main. Once PR is merged it will auto release the 0.0.9 version of SPI for prod codebase


## Steps to generate a spring boot project for given spec using gradle

Prerequisites:
Use Java8 or higher version.

1. Clone repository in local
```shell
git clone git@github.com:chargebee/cb-provider-spi.git
```

2. Navigate to the repository
```shell
cd cb-provider-spi
```

3. (a) Run the script to generate spring boot project for an openapi spec file with default configurations:
```shell
./setup_adapter_spring_boot.sh --spec <openapi spec file name>
```
3. (b) Run the script to generate spring boot project for an openapi spec file with custom configurations (params are optional, if not provided will take the default configurations) :
```shell
./setup_adapter_spring_boot.sh --java <version> --output <output_directory> --package <package_name> --spec <openapi spec file name>
```
Example:
```shell
./setup_adapter_spring_boot.sh --java 11 --output ../my-adapter --package com.adapter --spec openapi_tax.yml
```
Loading