Search in sources :

Example 1 with Relationship

use of com.yahoo.elide.swagger.property.Relationship in project elide by yahoo.

the class SwaggerBuilderTest method verifyDataRelationship.

/**
 * Verifies that the given model is of type 'Data' containing a 'Relationship' with the
 * correct type field.
 * @param model The model to check
 * @param refTypeName The type field to match against
 */
private void verifyDataRelationship(Model model, String refTypeName) {
    assertTrue((model instanceof com.yahoo.elide.swagger.model.Data));
    ArrayProperty data = (ArrayProperty) model.getProperties().get("data");
    Relationship relation = (Relationship) data.getItems();
    StringProperty type = (StringProperty) relation.getProperties().get("type");
    assertTrue(type.getEnum().contains(refTypeName));
}
Also used : ArrayProperty(io.swagger.models.properties.ArrayProperty) Relationship(com.yahoo.elide.swagger.property.Relationship) StringProperty(io.swagger.models.properties.StringProperty) Data(com.yahoo.elide.swagger.property.Data)

Example 2 with Relationship

use of com.yahoo.elide.swagger.property.Relationship in project elide by yahoo.

the class JsonApiModelResolver method resolve.

@Override
public Model resolve(java.lang.reflect.Type type, ModelConverterContext context, Iterator<ModelConverter> next) {
    if (!(type instanceof Class || type instanceof SimpleType || type instanceof Type)) {
        return super.resolve(type, context, next);
    }
    Type<?> clazzType = null;
    /*
         * If an Elide entity is an attribute somewhere in a model, the ModelResolver will
         * end up wrapping this as a SimpleType (rather than trying to resolve the entity class directly).
         */
    if (type instanceof SimpleType) {
        type = ((SimpleType) type).getRawClass();
        clazzType = ClassType.of((Class<?>) type);
    } else if (type instanceof Type) {
        clazzType = (Type<?>) type;
    } else if (type instanceof Class) {
        clazzType = ClassType.of((Class<?>) type);
    }
    /* Not an entity managed by Elide, let Swagger convert it */
    String typeAlias;
    try {
        typeAlias = dictionary.getJsonAliasFor(clazzType);
    } catch (IllegalArgumentException e) {
        return super.resolve(type, context, next);
    }
    Resource entitySchema = new Resource();
    entitySchema.description(getModelDescription(clazzType));
    entitySchema.setSecurityDescription(getClassPermissions(clazzType));
    /* Populate the attributes */
    List<String> attributeNames = dictionary.getAttributes(clazzType);
    for (String attributeName : attributeNames) {
        Type<?> attributeType = dictionary.getType(clazzType, attributeName);
        Property attribute = processAttribute(clazzType, attributeName, attributeType, context, next);
        entitySchema.addAttribute(attributeName, attribute);
    }
    /* Populate the relationships */
    List<String> relationshipNames = dictionary.getRelationships(clazzType);
    for (String relationshipName : relationshipNames) {
        Type<?> relationshipType = dictionary.getParameterizedType(clazzType, relationshipName);
        Relationship relationship = processRelationship(clazzType, relationshipName, relationshipType);
        if (relationship != null) {
            entitySchema.addRelationship(relationshipName, relationship);
        }
    }
    entitySchema.name(typeAlias);
    return entitySchema;
}
Also used : SimpleType(com.fasterxml.jackson.databind.type.SimpleType) SimpleType(com.fasterxml.jackson.databind.type.SimpleType) ClassType(com.yahoo.elide.core.type.ClassType) Type(com.yahoo.elide.core.type.Type) Relationship(com.yahoo.elide.swagger.property.Relationship) Resource(com.yahoo.elide.swagger.model.Resource) ApiModelProperty(io.swagger.annotations.ApiModelProperty) Property(io.swagger.models.properties.Property)

Example 3 with Relationship

use of com.yahoo.elide.swagger.property.Relationship in project elide by yahoo.

the class SwaggerBuilderTest method verifyDataRelationship.

/**
 * Verifies that the given property is of type 'Data' containing a 'Relationship' with the
 * correct type field.
 * @param property The property to check
 * @param refTypeName The type field to match against
 */
private void verifyDataRelationship(Property property, String refTypeName) {
    assertTrue((property instanceof Data));
    ArrayProperty data = (ArrayProperty) ((Data) property).getProperties().get("data");
    Relationship relation = (Relationship) data.getItems();
    StringProperty type = (StringProperty) relation.getProperties().get("type");
    assertTrue(type.getEnum().contains(refTypeName));
}
Also used : ArrayProperty(io.swagger.models.properties.ArrayProperty) Relationship(com.yahoo.elide.swagger.property.Relationship) StringProperty(io.swagger.models.properties.StringProperty) Data(com.yahoo.elide.swagger.property.Data)

Example 4 with Relationship

use of com.yahoo.elide.swagger.property.Relationship in project elide by yahoo.

the class JsonApiModelResolver method processRelationship.

private Relationship processRelationship(Type<?> clazz, String relationshipName, Type<?> relationshipClazz) {
    Relationship relationship = null;
    try {
        relationship = new Relationship(dictionary.getJsonAliasFor(relationshipClazz));
    /* Skip the relationship if it is not bound in the dictionary */
    } catch (IllegalArgumentException e) {
        return relationship;
    }
    String description = getFieldDescription(clazz, relationshipName);
    String permissions = getFieldPermissions(clazz, relationshipName);
    relationship.setDescription(StringUtils.defaultIfEmpty(joinNonEmpty("\n", description, permissions), null));
    relationship.setExample((Object) StringUtils.defaultIfEmpty(getFieldExample(clazz, relationshipName), null));
    relationship.setReadOnly(getFieldReadOnly(clazz, relationshipName));
    relationship.setRequired(getFieldRequired(clazz, relationshipName));
    return relationship;
}
Also used : Relationship(com.yahoo.elide.swagger.property.Relationship)

Example 5 with Relationship

use of com.yahoo.elide.swagger.property.Relationship in project elide by yahoo.

the class SwaggerBuilder method build.

/**
 * Builds a swagger object.
 * @return the constructed 'Swagger' object
 */
public Swagger build() {
    /* Used to convert Elide POJOs into Swagger Model objects */
    ModelConverters converters = ModelConverters.getInstance();
    ModelConverter converter = new JsonApiModelResolver(dictionary);
    converters.addConverter(converter);
    String apiVersion = swagger.getInfo().getVersion();
    if (apiVersion == null) {
        apiVersion = NO_VERSION;
    }
    if (allClasses.isEmpty()) {
        allClasses = dictionary.getBoundClassesByVersion(apiVersion);
    } else {
        allClasses = Sets.intersection(dictionary.getBoundClassesByVersion(apiVersion), allClasses);
        if (allClasses.isEmpty()) {
            throw new IllegalArgumentException("None of the provided classes are exported by Elide");
        }
    }
    /*
         * Create a Model for each Elide entity.
         * Elide entity could be of ClassType or DynamicType.
         * For ClassType, extract the class and pass it to ModelConverters#readAll method.
         * ModelConverters#readAll doesn't support Elide Dynamic Type, so calling the
         * JsonApiModelResolver#resolve method directly when its not a ClassType.
         */
    Map<String, Model> models = new HashMap<>();
    for (Type<?> clazz : allClasses) {
        if (clazz instanceof ClassType) {
            models.putAll(converters.readAll(((ClassType) clazz).getCls()));
        } else {
            ModelConverterContextImpl context = new ModelConverterContextImpl(Arrays.asList(converter));
            context.resolve(clazz);
            models.putAll(context.getDefinedModels());
        }
    }
    swagger.setDefinitions(models);
    rootClasses = allClasses.stream().filter(dictionary::isRoot).collect(Collectors.toSet());
    /* Find all the paths starting from the root entities. */
    Set<PathMetaData> pathData = rootClasses.stream().map(this::find).flatMap(Collection::stream).collect(Collectors.toSet());
    /* Prune the discovered paths to remove redundant elements */
    Set<PathMetaData> toRemove = new HashSet<>();
    pathData.stream().collect(Collectors.groupingBy(PathMetaData::getRootType)).values().forEach(pathSet -> {
        for (PathMetaData path : pathSet) {
            for (PathMetaData compare : pathSet) {
                /*
                             * We don't prune paths that are redundant with root collections to allow both BOTH
                             * root collection urls as well as relationship urls.
                             */
                if (compare.lineage.isEmpty() || path == compare) {
                    continue;
                }
                if (compare.shorterThan(path)) {
                    toRemove.add(path);
                    break;
                }
            }
        }
    });
    pathData = Sets.difference(pathData, toRemove);
    /* Each path constructs 3 URLs (collection, instance, and relationship) */
    for (PathMetaData pathDatum : pathData) {
        swagger.path(pathDatum.getCollectionUrl(), pathDatum.getCollectionPath());
        swagger.path(pathDatum.getUrl(), pathDatum.getInstancePath());
        /* We only construct relationship URLs if the entity is not a root collection */
        if (!pathDatum.lineage.isEmpty()) {
            swagger.path(pathDatum.getRelationshipUrl(), pathDatum.getRelationshipPath());
        }
    }
    /* We create Swagger 'tags' for each entity so Swagger UI organizes the paths by entities */
    List<Tag> tags = allClasses.stream().map((clazz) -> dictionary.getJsonAliasFor(clazz)).map((alias) -> new Tag().name(alias)).collect(Collectors.toList());
    swagger.tags(tags);
    return swagger;
}
Also used : Arrays(java.util.Arrays) ModelConverters(io.swagger.converter.ModelConverters) Getter(lombok.Getter) Swagger(io.swagger.models.Swagger) Tag(io.swagger.models.Tag) StringProperty(io.swagger.models.properties.StringProperty) Json(io.swagger.util.Json) HashMap(java.util.HashMap) ClassType(com.yahoo.elide.core.type.ClassType) Stack(java.util.Stack) Model(io.swagger.models.Model) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Path(io.swagger.models.Path) Map(java.util.Map) NO_VERSION(com.yahoo.elide.core.dictionary.EntityDictionary.NO_VERSION) Datum(com.yahoo.elide.swagger.model.Datum) ModelConverter(io.swagger.converter.ModelConverter) BodyParameter(io.swagger.models.parameters.BodyParameter) PathParameter(io.swagger.models.parameters.PathParameter) Collection(java.util.Collection) Set(java.util.Set) Parameter(io.swagger.models.parameters.Parameter) ModelConverterContextImpl(io.swagger.converter.ModelConverterContextImpl) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Sets(com.google.common.collect.Sets) Info(io.swagger.models.Info) QueryParameter(io.swagger.models.parameters.QueryParameter) Objects(java.util.Objects) Response(io.swagger.models.Response) List(java.util.List) Type(com.yahoo.elide.core.type.Type) Operator(com.yahoo.elide.core.filter.Operator) Relationship(com.yahoo.elide.swagger.property.Relationship) Queue(java.util.Queue) ArrayDeque(java.util.ArrayDeque) RelationshipType(com.yahoo.elide.core.dictionary.RelationshipType) Data(com.yahoo.elide.swagger.model.Data) HashMap(java.util.HashMap) ClassType(com.yahoo.elide.core.type.ClassType) ModelConverter(io.swagger.converter.ModelConverter) Model(io.swagger.models.Model) ModelConverters(io.swagger.converter.ModelConverters) Tag(io.swagger.models.Tag) ModelConverterContextImpl(io.swagger.converter.ModelConverterContextImpl) HashSet(java.util.HashSet)

Aggregations

Relationship (com.yahoo.elide.swagger.property.Relationship)5 StringProperty (io.swagger.models.properties.StringProperty)3 ClassType (com.yahoo.elide.core.type.ClassType)2 Type (com.yahoo.elide.core.type.Type)2 Data (com.yahoo.elide.swagger.property.Data)2 ArrayProperty (io.swagger.models.properties.ArrayProperty)2 SimpleType (com.fasterxml.jackson.databind.type.SimpleType)1 Sets (com.google.common.collect.Sets)1 EntityDictionary (com.yahoo.elide.core.dictionary.EntityDictionary)1 NO_VERSION (com.yahoo.elide.core.dictionary.EntityDictionary.NO_VERSION)1 RelationshipType (com.yahoo.elide.core.dictionary.RelationshipType)1 Operator (com.yahoo.elide.core.filter.Operator)1 Data (com.yahoo.elide.swagger.model.Data)1 Datum (com.yahoo.elide.swagger.model.Datum)1 Resource (com.yahoo.elide.swagger.model.Resource)1 ApiModelProperty (io.swagger.annotations.ApiModelProperty)1 ModelConverter (io.swagger.converter.ModelConverter)1 ModelConverterContextImpl (io.swagger.converter.ModelConverterContextImpl)1 ModelConverters (io.swagger.converter.ModelConverters)1 Info (io.swagger.models.Info)1