Skip to content

Commit

Permalink
[SHIBUI-906]
Browse files Browse the repository at this point in the history
Fixed a typo: Shematype -> SchemaType
Pulled json generation out of controllers and in to a service.
Added new controller for building Entity Attributes Filter schema.
Added a "definition" block to the EAF schema json. Not sure we're keeping
it though. Need to check with Ryan.
  • Loading branch information
Bill Smith committed Nov 6, 2018
1 parent c391456 commit 10ec71c
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package edu.internet2.tier.shibboleth.admin.ui.controller

import com.fasterxml.jackson.databind.ObjectMapper
import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation
import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocationRegistry
import edu.internet2.tier.shibboleth.admin.ui.service.JsonSchemaBuilderService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

import javax.annotation.PostConstruct

import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.entityAttributesFiltersSchema
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR

/**
* Controller implementing REST resource responsible for exposing structure definition for metadata sources user
* interface in terms of JSON schema.
*
* @author Dmitriy Kopylenko
* @author Bill Smith (wsmith@unicon.net)
*/
@RestController
@RequestMapping('/api/ui/EntityAttributesFilters')
class EntityAttributesFiltersUiDefinitionController {

@Autowired
JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry

JsonSchemaResourceLocation jsonSchemaLocation

@Autowired
ObjectMapper jacksonObjectMapper

@Autowired
JsonSchemaBuilderService jsonSchemaBuilderService

@GetMapping
ResponseEntity<?> getUiDefinitionJsonSchema() {
try {
def parsedJson = jacksonObjectMapper.readValue(this.jsonSchemaLocation.url, Map)
jsonSchemaBuilderService.addReleaseAttributesToJson(parsedJson['properties']['attributeRelease']['widget'])
jsonSchemaBuilderService.addRelyingPartyOverridesToJson(parsedJson['properties']['relyingPartyOverrides'])
jsonSchemaBuilderService.addRelyingPartyOverridesCollectionDefinitionsToJson(parsedJson["definitions"])
return ResponseEntity.ok(parsedJson)
}
catch (Exception e) {
e.printStackTrace()
return ResponseEntity.status(INTERNAL_SERVER_ERROR)
.body([jsonParseError : e.getMessage(),
sourceUiSchemaDefinitionFile: this.jsonSchemaLocation.url])
}
}

@PostConstruct
void init() {
this.jsonSchemaLocation = entityAttributesFiltersSchema(this.jsonSchemaResourceLocationRegistry);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package edu.internet2.tier.shibboleth.admin.ui.controller

import com.fasterxml.jackson.databind.ObjectMapper
import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration
import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup
import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation
import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocationRegistry
import org.springframework.beans.factory.BeanInitializationException
import edu.internet2.tier.shibboleth.admin.ui.service.JsonSchemaBuilderService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
Expand All @@ -15,7 +13,6 @@ import org.springframework.web.bind.annotation.RestController
import javax.annotation.PostConstruct

import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.metadataSourcesSchema
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.ShemaType.METADATA_SOURCES
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR

/**
Expand All @@ -38,15 +35,15 @@ class MetadataSourcesUiDefinitionController {
ObjectMapper jacksonObjectMapper

@Autowired
CustomPropertiesConfiguration customPropertiesConfiguration
JsonSchemaBuilderService jsonSchemaBuilderService

@GetMapping
ResponseEntity<?> getUiDefinitionJsonSchema() {
try {
def parsedJson = jacksonObjectMapper.readValue(this.jsonSchemaLocation.url, Map)
addReleaseAttributesToJson(parsedJson['properties']['attributeRelease']['widget'])
addRelyingPartyOverridesToJson(parsedJson['properties']['relyingPartyOverrides'])
addRelyingPartyOverridesCollectionDefinitions(parsedJson["definitions"])
jsonSchemaBuilderService.addReleaseAttributesToJson(parsedJson['properties']['attributeRelease']['widget'])
jsonSchemaBuilderService.addRelyingPartyOverridesToJson(parsedJson['properties']['relyingPartyOverrides'])
jsonSchemaBuilderService.addRelyingPartyOverridesCollectionDefinitionsToJson(parsedJson["definitions"])
return ResponseEntity.ok(parsedJson)
}
catch (Exception e) {
Expand All @@ -61,52 +58,4 @@ class MetadataSourcesUiDefinitionController {
void init() {
this.jsonSchemaLocation = metadataSourcesSchema(this.jsonSchemaResourceLocationRegistry);
}

private void addReleaseAttributesToJson(Object json) {
json['data'] = customPropertiesConfiguration.getAttributes().collect {
[key: it['name'], label: it['displayName']]
}
}

private void addRelyingPartyOverridesToJson(Object json) {
def properties = [:]
customPropertiesConfiguration.getOverrides().each {
def property
if (it['displayType'] == 'list'
|| it['displayType'] == 'set') {
property = [$ref: '#/definitions/' + it['name']]
} else {
property =
[title : it['displayName'],
description: it['helpText'],
type : it['displayType'],
default : it['defaultValue']]
}
properties[(String) it['name']] = property
}
json['properties'] = properties
}

private void addRelyingPartyOverridesCollectionDefinitions(Object json) {
customPropertiesConfiguration.getOverrides().stream().filter {
it -> it['displayType'] && (it['displayType'] == 'list' || it['displayType'] == 'set')
}.each {
def definition = [title : it['displayName'],
description: it['helpText'],
type : 'array',
default : null]
if (it['displayType'] == 'set') {
definition['uniqueItems'] = true
} else if (it['displayType'] == 'list') {
definition['uniqueItems'] = false
}
def items = [type : 'string',
minLength: '1', // TODO: should this be configurable?
maxLength: '255'] //TODO: or this?
items.widget = [id: 'datalist', data: it['defaultValues']]

definition['items'] = items
json[(String) it['name']] = definition
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package edu.internet2.tier.shibboleth.admin.ui.jsonschema

import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation
import mjson.Json
import org.springframework.beans.factory.BeanInitializationException
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.core.MethodParameter
import org.springframework.http.HttpInputMessage
Expand All @@ -18,7 +17,6 @@ import javax.annotation.PostConstruct
import java.lang.reflect.Type

import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.metadataSourcesSchema
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.ShemaType.METADATA_SOURCES

/**
* Controller advice implementation for validating relying party overrides payload coming from UI layer
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package edu.internet2.tier.shibboleth.admin.ui.service

import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration
import org.springframework.beans.factory.annotation.Autowired

/**
* @author Bill Smith (wsmith@unicon.net)
*/
class JsonSchemaBuilderService {

@Autowired
CustomPropertiesConfiguration customPropertiesConfiguration

void addReleaseAttributesToJson(Object json) {
json['data'] = customPropertiesConfiguration.getAttributes().collect {
[key: it['name'], label: it['displayName']]
}
}

void addRelyingPartyOverridesToJson(Object json) {
def properties = [:]
customPropertiesConfiguration.getOverrides().each {
def property
if (it['displayType'] == 'list'
|| it['displayType'] == 'set') {
property = [$ref: '#/definitions/' + it['name']]
} else {
property =
[title : it['displayName'],
description: it['helpText'],
type : it['displayType'],
default : it['defaultValue']]
}
properties[(String) it['name']] = property
}
json['properties'] = properties
}

void addRelyingPartyOverridesCollectionDefinitionsToJson(Object json) {
customPropertiesConfiguration.getOverrides().stream().filter {
it -> it['displayType'] && (it['displayType'] == 'list' || it['displayType'] == 'set')
}.each {
def definition = [title : it['displayName'],
description: it['helpText'],
type : 'array',
default : null]
if (it['displayType'] == 'set') {
definition['uniqueItems'] = true
} else if (it['displayType'] == 'list') {
definition['uniqueItems'] = false
}
def items = [type : 'string',
minLength: '1', // TODO: should this be configurable?
maxLength: '255'] //TODO: or this?
items.widget = [id: 'datalist', data: it['defaultValues']]

definition['items'] = items
json[(String) it['name']] = definition
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package edu.internet2.tier.shibboleth.admin.ui.configuration;

import com.fasterxml.jackson.databind.ObjectMapper;
import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation;
import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocationRegistry;
import edu.internet2.tier.shibboleth.admin.ui.service.JsonSchemaBuilderService;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;

import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.*;
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.ShemaType.ENTITY_ATTRIBUTES_FILTERS;
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.ShemaType.METADATA_SOURCES;
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.ENTITY_ATTRIBUTES_FILTERS;
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.METADATA_SOURCES;

/**
* @author Dmitriy Kopylenko
Expand Down Expand Up @@ -47,4 +47,9 @@ public JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry(Res
.build());

}

@Bean
public JsonSchemaBuilderService jsonSchemaBuilderService() {
return new JsonSchemaBuilderService();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
*/
class InMemoryJsonSchemaResourceLocationRegistry implements JsonSchemaResourceLocationRegistry {

private Map<JsonSchemaResourceLocation.ShemaType, JsonSchemaResourceLocation> schemaLocations =
new EnumMap<>(JsonSchemaResourceLocation.ShemaType.class);
private Map<JsonSchemaResourceLocation.SchemaType, JsonSchemaResourceLocation> schemaLocations =
new EnumMap<>(JsonSchemaResourceLocation.SchemaType.class);


@Override
public JsonSchemaResourceLocationRegistry register(JsonSchemaResourceLocation.ShemaType type, JsonSchemaResourceLocation location) {
public JsonSchemaResourceLocationRegistry register(JsonSchemaResourceLocation.SchemaType type, JsonSchemaResourceLocation location) {
this.schemaLocations.put(type, location);
return this;
}

@Override
public Optional<JsonSchemaResourceLocation> lookup(JsonSchemaResourceLocation.ShemaType type) {
public Optional<JsonSchemaResourceLocation> lookup(JsonSchemaResourceLocation.SchemaType type) {
return Optional.ofNullable(this.schemaLocations.get(type));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package edu.internet2.tier.shibboleth.admin.ui.jsonschema;

import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.ShemaType.METADATA_SOURCES;
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.ENTITY_ATTRIBUTES_FILTERS;
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.METADATA_SOURCES;

/**
* Utility methods for common JSON schema types lookups.
Expand All @@ -21,4 +22,17 @@ public static JsonSchemaResourceLocation metadataSourcesSchema(JsonSchemaResourc
.lookup(METADATA_SOURCES)
.orElseThrow(() -> new IllegalStateException("JSON schema resource location for metadata sources is not registered."));
}

/**
* Searches entity attributes filters JSON schema resource location object in the given location registry.
*
* @param resourceLocationRegistry
* @returnentity attributes filters JSON schema resource location object
* @throws IllegalStateException if schema is not found in the given registry
*/
public static JsonSchemaResourceLocation entityAttributesFiltersSchema(JsonSchemaResourceLocationRegistry resourceLocationRegistry) {
return resourceLocationRegistry
.lookup(ENTITY_ATTRIBUTES_FILTERS)
.orElseThrow(() -> new IllegalStateException("JSON schema resource location for metadata sources is not registered."));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public static JsonSchemaResourceLocation newSchemaLocation(String jsonSchemaLoca
}
}

public enum ShemaType {
public enum SchemaType {
METADATA_SOURCES, ENTITY_ATTRIBUTES_FILTERS
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ public interface JsonSchemaResourceLocationRegistry {
* @param type of JSON schema
* @param location of JSON schema resource
*/
JsonSchemaResourceLocationRegistry register(JsonSchemaResourceLocation.ShemaType type, JsonSchemaResourceLocation location);
JsonSchemaResourceLocationRegistry register(JsonSchemaResourceLocation.SchemaType type, JsonSchemaResourceLocation location);

/**
* Look up json schema resource location by given schema type.
*
* @param type type of JSON schema
* @return optional location of JSON schema resource
*/
Optional<JsonSchemaResourceLocation> lookup(JsonSchemaResourceLocation.ShemaType type);
Optional<JsonSchemaResourceLocation> lookup(JsonSchemaResourceLocation.SchemaType type);

/**
* Factory method.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,5 +222,7 @@
"attributeRelease"
]
}
]
],
"definitions": {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import org.springframework.test.context.ActiveProfiles
import spock.lang.Specification

import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.*
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.ShemaType.METADATA_SOURCES
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.METADATA_SOURCES

/**
* @author Dmitriy Kopylenko
Expand Down

0 comments on commit 10ec71c

Please sign in to comment.