Skip to content

Commit

Permalink
AbstractProperties
Browse files Browse the repository at this point in the history
  • Loading branch information
nofateg authored Apr 29, 2024
1 parent 2fbc081 commit 81a20cb
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public static void add( AbstractJsonSchemaValidator<?> validator ) {
}

private Object parseWithTemplate( String schema, SchemaStorage storage ) {
var obj = Binder.hoconWithoutSystemProperties.unmarshal( Object.class, schema );
Object obj = Binder.hoconWithoutSystemProperties.unmarshal( Object.class, schema );
resolveTemplates( obj, storage );
log.trace( "schema = {}", Binder.json.marshal( obj ) );
return obj;
Expand All @@ -107,22 +107,21 @@ private Object parseWithTemplate( String schema, SchemaStorage storage ) {
@SuppressWarnings( "unchecked" )
private void resolveTemplates( Object obj, SchemaStorage storage ) {
if( obj instanceof Map<?, ?> ) {
var map = ( Map<Object, Object> ) obj;
var templatePath = map.get( "template" );
Map<Object, Object> map = ( Map<Object, Object> ) obj;
Object templatePath = map.get( "template" );
if( templatePath != null ) {
Preconditions.checkArgument( templatePath instanceof String );

var templateStr = storage.get( ( String ) templatePath );
var templateMap = Binder.hoconWithoutSystemProperties.unmarshal( Object.class, templateStr );
String templateStr = storage.get( ( String ) templatePath );
Object templateMap = Binder.hoconWithoutSystemProperties.unmarshal( Object.class, templateStr );
log.trace( "template path = {}, template = {}", templatePath, templateStr );

map.remove( "template" );
addTemplate( map, templateMap );
}

map.values().forEach( obj1 -> resolveTemplates( obj1, storage ) );
} else if( obj instanceof List<?> ) {
var list = ( List<?> ) obj;
} else if( obj instanceof List<?> list ) {
list.forEach( obj1 -> resolveTemplates( obj1, storage ) );
}
}
Expand All @@ -132,15 +131,17 @@ private void addTemplate( Object sl, Object sr ) {
if( sl instanceof Map<?, ?> ) {
Preconditions.checkArgument( sr instanceof Map<?, ?> );

var mapl = ( Map<Object, Object> ) sl;
var mapr = ( Map<Object, Object> ) sr;
mapr.forEach( ( key, vr ) -> {
var vl = mapl.get( key );
Map<Object, Object> mapl = ( Map<Object, Object> ) sl;
Map<Object, Object> mapr = ( Map<Object, Object> ) sr;
for( Map.Entry<Object, Object> entry : mapr.entrySet() ) {
Object key = entry.getKey();
Object vr = entry.getValue();
Object vl = mapl.get( key );
if( vl != null ) {
addTemplate( vl, vr );
} else
mapl.put( key, vr );
} );
}
}
}

Expand Down Expand Up @@ -194,7 +195,7 @@ AbstractSchemaASTWrapper parse( String schema, SchemaStorage storage ) {
}

AbstractSchemaASTWrapper parse( String schemaName, String schema, String rootPath, SchemaStorage storage ) {
var context = new JsonSchemaParserContext(
JsonSchemaParserContext context = new JsonSchemaParserContext(
schemaName,
null, "",
this::parse,
Expand All @@ -204,7 +205,7 @@ AbstractSchemaASTWrapper parse( String schemaName, String schema, String rootPat
}

private AbstractSchemaASTWrapper parse( JsonSchemaParserContext context ) {
var schemaParser = validators.get( context.schemaType );
AbstractJsonSchemaValidator<? extends AbstractSchemaAST<?>> schemaParser = validators.get( context.schemaType );
if( schemaParser != null ) {
return schemaParser.parse( context );
} else {
Expand All @@ -215,7 +216,7 @@ private AbstractSchemaASTWrapper parse( JsonSchemaParserContext context ) {
}

public List<String> partialValidate( Object root, Object json, String path, boolean ignoreRequiredDefault ) {
var traverseResult = SchemaPath.traverse( this.schema, path );
SchemaPath.Result traverseResult = SchemaPath.traverse( this.schema, path );
final AbstractSchemaAST partialSchema = traverseResult.schema
.orElseThrow( () -> new ValidationSyntaxException( "path " + path + " not found" ) );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.apache.commons.io.FilenameUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public final class ResourceSchemaStorage implements SchemaStorage {
Expand All @@ -41,20 +42,24 @@ private ResourceSchemaStorage() {

@Override
public String get( String name ) {
var ext = FilenameUtils.getExtension( name );
var prefix = FilenameUtils.removeExtension( name );
var fileName = FilenameUtils.removeExtension( FilenameUtils.getName( name ) );
String ext = FilenameUtils.getExtension( name );
String prefix = FilenameUtils.removeExtension( name );
String fileName = FilenameUtils.removeExtension( FilenameUtils.getName( name ) );

var conf = Resources.readOrThrow( getClass(), name, ContentReader.ofString() );
if( "yaml".equalsIgnoreCase( ext ) ) conf = Binder.json.marshal( Binder.yaml.unmarshal( Map.class, conf ) );
String conf = Resources.readOrThrow( getClass(), name, ContentReader.ofString() );
if( "yaml".equalsIgnoreCase( ext ) ) {
conf = Binder.json.marshal( Binder.yaml.unmarshal( Map.class, conf ) );
}

var extConf = Resources.readStrings( getClass(), prefix + "/" + fileName + ".conf" );
var extJson = Resources.readStrings( getClass(), prefix + "/" + fileName + ".json" );
var extYaml = Resources.readStrings( getClass(), prefix + "/" + fileName + ".yaml" );
List<String> extConf = Resources.readStrings( getClass(), prefix + "/" + fileName + ".conf" );
List<String> extJson = Resources.readStrings( getClass(), prefix + "/" + fileName + ".json" );
List<String> extYaml = Resources.readStrings( getClass(), prefix + "/" + fileName + ".yaml" );

if( extConf.isEmpty() && extJson.isEmpty() && extYaml.isEmpty() ) return conf;
if( extConf.isEmpty() && extJson.isEmpty() && extYaml.isEmpty() ) {
return conf;
}

var list = new ArrayList<String>();
ArrayList<String> list = new ArrayList<>();
list.addAll( extConf );
list.addAll( extJson );
list.addAll( Lists.map( extYaml, y -> Binder.json.marshal( Binder.yaml.unmarshal( Map.class, y ) ) ) );
Expand Down
37 changes: 37 additions & 0 deletions oap-stdlib/src/main/java/oap/json/AbstractProperties.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package oap.json;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import oap.json.properties.PropertiesDeserializer;

import javax.annotation.Nullable;
import java.util.LinkedHashMap;
import java.util.Map;

@ToString
@EqualsAndHashCode
public abstract class AbstractProperties {
@JsonIgnore
private final LinkedHashMap<String, Object> properties = new LinkedHashMap<>();

@JsonAnySetter
@JsonDeserialize( contentUsing = PropertiesDeserializer.class )
public void putProperty( String name, Object value ) {
properties.put( name, value );
}

@JsonAnyGetter
public Map<String, Object> getProperties() {
return properties;
}

@SuppressWarnings( "unchecked" )
@Nullable
public <T> T getProperty( String property ) {
return ( T ) properties.get( property );
}
}
23 changes: 23 additions & 0 deletions oap-ws/oap-ws-admin-ws/src/main/java/oap/ws/admin/SchemaWS.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package oap.ws.admin;

import oap.http.Http;
import oap.json.Binder;
import oap.json.schema.ResourceSchemaStorage;
import oap.ws.Response;
import oap.ws.WsMethod;
import oap.ws.WsParam;

import java.util.Map;

import static oap.ws.WsParam.From.QUERY;

public class SchemaWS {
@WsMethod( path = "/" )
public Response getSchema( @WsParam( from = QUERY ) String path ) {
String json = ResourceSchemaStorage.INSTANCE.get( path );

return new Response( Http.StatusCode.OK )
.withBody( Binder.json.marshalWithDefaultPrettyPrinter( Binder.json.unmarshal( Map.class, json ) ), true )
.withContentType( Http.ContentType.APPLICATION_JSON );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ services {
port = httpprivate
}
}

ws-schema {
implementation = oap.ws.admin.SchemaWS
ws-service {
path = system/admin/schema
port = httpprivate
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* The MIT License (MIT)
*
* Copyright (c) Open Application Platform Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package oap.ws.admin;

import oap.application.testng.KernelFixture;
import oap.testng.Fixtures;
import oap.testng.TestDirectoryFixture;
import org.testng.annotations.Test;

import static oap.http.test.HttpAsserts.assertGet;
import static oap.io.Resources.urlOrThrow;

public class SchemaWSTest extends Fixtures {
private final KernelFixture kernel;

public SchemaWSTest() {
TestDirectoryFixture testDirectoryFixture = fixture( new TestDirectoryFixture() );
kernel = fixture( new KernelFixture( testDirectoryFixture, urlOrThrow( getClass(), "/application.test.conf" ) ) );
}

@Test
public void testSchema() {
assertGet( kernel.httpUrl( "/system/admin/schema?path=/schema/test-schema.conf" ) )
.isOk()
.respondedJson( """
{
"properties" : {
"a" : {
"type" : "string"
},
"b" : {
"type" : "string"
}
},
"type" : "object"
}
""" );

}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
boot.main = oap-ws-admin-ws-test

services {
oap.oap-http-server.parameters.port = ${TEST_HTTP_PORT}
oap-http {
oap-http-server.parameters {
defaultPort.httpPort = ${TEST_HTTP_PORT}
additionalHttpPorts.httpprivate = ${TEST_HTTP_PORT}
}
}

oap-ws.session-manager.parameters.cookieDomain: ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
type = object
properties {
a.type = string
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
properties {
b.type = string
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ public JsonValidatorPeer( WsValidateJson validate, Reflection.Method targetMetho
@Override
public ValidationErrors validate( Object value, Map<Reflection.Parameter, Object> originalValues ) {
try {
var mapValue = Binder.json.unmarshal( Map.class, ( String ) value );
var factory = getJsonSchema( originalValues );
Map mapValue = Binder.json.unmarshal( Map.class, ( String ) value );
JsonSchema factory = getJsonSchema( originalValues );
return ValidationErrors.errors( factory.validate( mapValue, validate.ignoreRequired() ) );
} catch( JsonException e ) {
throw new WsClientException( e.getMessage(), e );
}
}

private JsonSchema getJsonSchema( Map<Reflection.Parameter, Object> originalValues ) {
if( !dynamic ) return cache.computeIfAbsent( Strings.UNDEFINED, s -> JsonSchema.schema( schemaRef ) );
if( !dynamic ) return cache.computeIfAbsent( Strings.UNDEFINED, _ -> JsonSchema.schema( schemaRef ) );

log.trace( "dynamic schema ref {}", schemaRef );

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
</distributionManagement>

<properties>
<oap.project.version>22.1.4</oap.project.version>
<oap.project.version>22.1.5</oap.project.version>

<oap.deps.config.version>21.0.0</oap.deps.config.version>
<oap.deps.oap-teamcity.version>21.0.1</oap.deps.oap-teamcity.version>
Expand Down

0 comments on commit 81a20cb

Please sign in to comment.