Search in sources :

Example 6 with BatchFinderSchema

use of com.linkedin.restli.restspec.BatchFinderSchema in project rest.li by linkedin.

the class RestLiResourceRelationship method findDataModels.

private void findDataModels() {
    final ResourceSchemaVisitior visitor = new BaseResourceSchemaVisitor() {

        @Override
        public void visitResourceSchema(VisitContext visitContext, ResourceSchema resourceSchema) {
            final String schema = resourceSchema.getSchema();
            // ActionSet resources do not have a schema
            if (schema != null) {
                final NamedDataSchema schemaSchema = extractSchema(schema);
                if (schemaSchema != null) {
                    connectSchemaToResource(visitContext, schemaSchema);
                }
            }
        }

        @Override
        public void visitCollectionResource(VisitContext visitContext, CollectionSchema collectionSchema) {
            connectErrorDetailTypeToResource(visitContext, collectionSchema);
            final IdentifierSchema id = collectionSchema.getIdentifier();
            final NamedDataSchema typeSchema = extractSchema(id.getType());
            if (typeSchema != null) {
                connectSchemaToResource(visitContext, typeSchema);
            }
            final String params = id.getParams();
            if (params != null) {
                final NamedDataSchema paramsSchema = extractSchema(params);
                if (paramsSchema != null) {
                    connectSchemaToResource(visitContext, paramsSchema);
                }
            }
        }

        @Override
        public void visitAssociationResource(VisitContext visitContext, AssociationSchema associationSchema) {
            connectErrorDetailTypeToResource(visitContext, associationSchema);
            for (AssocKeySchema key : associationSchema.getAssocKeys()) {
                final NamedDataSchema keyTypeSchema = extractSchema(key.getType());
                if (keyTypeSchema != null) {
                    connectSchemaToResource(visitContext, keyTypeSchema);
                }
            }
        }

        @Override
        public void visitSimpleResource(VisitContext visitContext, SimpleSchema simpleSchema) {
            connectErrorDetailTypeToResource(visitContext, simpleSchema);
        }

        @Override
        public void visitActionSetResource(VisitContext visitContext, ActionsSetSchema actionSetSchema) {
            connectErrorDetailTypeToResource(visitContext, actionSetSchema);
        }

        @Override
        public void visitParameter(VisitContext visitContext, RecordTemplate parentResource, Object parentMethodSchema, ParameterSchema parameterSchema) {
            String parameterTypeString = parameterSchema.getType();
            if (// the parameter type field contains a inline schema, so we traverse into it
            isInlineSchema(parameterTypeString)) {
                visitInlineSchema(visitContext, parameterTypeString);
            } else {
                final NamedDataSchema schema;
                // grab the schema name from it
                if (parameterSchema.hasItems()) {
                    schema = extractSchema(parameterSchema.getItems());
                } else // the only remaining possibility is that the type field contains the name of a data schema
                {
                    schema = extractSchema(parameterTypeString);
                }
                if (schema != null) {
                    connectSchemaToResource(visitContext, schema);
                }
            }
        }

        @Override
        public void visitRestMethod(VisitContext visitContext, RecordTemplate parentResource, RestMethodSchema restMethodSchema) {
            connectErrorDetailTypeToResource(visitContext, restMethodSchema);
        }

        @Override
        public void visitFinder(VisitContext visitContext, RecordTemplate parentResource, FinderSchema finderSchema) {
            connectErrorDetailTypeToResource(visitContext, finderSchema);
            final MetadataSchema metadata = finderSchema.getMetadata();
            if (metadata != null) {
                final NamedDataSchema metadataTypeSchema = extractSchema(metadata.getType());
                if (metadataTypeSchema != null) {
                    connectSchemaToResource(visitContext, metadataTypeSchema);
                }
            }
        }

        @Override
        public void visitBatchFinder(VisitContext visitContext, RecordTemplate parentResource, BatchFinderSchema batchFinderSchema) {
            connectErrorDetailTypeToResource(visitContext, batchFinderSchema);
            final MetadataSchema metadata = batchFinderSchema.getMetadata();
            if (metadata != null) {
                final NamedDataSchema metadataTypeSchema = extractSchema(metadata.getType());
                if (metadataTypeSchema != null) {
                    connectSchemaToResource(visitContext, metadataTypeSchema);
                }
            }
        }

        @Override
        public void visitAction(VisitContext visitContext, RecordTemplate parentResource, ResourceLevel resourceLevel, ActionSchema actionSchema) {
            connectErrorDetailTypeToResource(visitContext, actionSchema);
            final String returns = actionSchema.getReturns();
            if (returns != null) {
                if (// the parameter type field contains a inline schema, so we traverse into it
                isInlineSchema(returns)) {
                    visitInlineSchema(visitContext, returns);
                } else // otherwise the type field contains the name of a data schema
                {
                    final NamedDataSchema returnsSchema = extractSchema(returns);
                    if (returnsSchema != null) {
                        connectSchemaToResource(visitContext, returnsSchema);
                    }
                }
            }
            final StringArray throwsArray = actionSchema.getThrows();
            if (throwsArray != null) {
                for (String errorName : throwsArray) {
                    final NamedDataSchema errorSchema = extractSchema(errorName);
                    if (errorSchema != null) {
                        connectSchemaToResource(visitContext, errorSchema);
                    }
                }
            }
        }

        private boolean isInlineSchema(String schemaString) {
            return schemaString.startsWith("{");
        }

        private void visitInlineSchema(VisitContext visitContext, String schemaString) {
            DataSchema schema = DataTemplateUtil.parseSchema(schemaString, _schemaResolver, SchemaFormatType.PDSC);
            if (schema instanceof ArrayDataSchema) {
                DataSchema itemSchema = ((ArrayDataSchema) schema).getItems();
                if (itemSchema instanceof NamedDataSchema) {
                    connectSchemaToResource(visitContext, (NamedDataSchema) itemSchema);
                }
            }
            if (schema instanceof MapDataSchema) {
                DataSchema valueSchema = ((MapDataSchema) schema).getValues();
                if (valueSchema instanceof NamedDataSchema) {
                    connectSchemaToResource(visitContext, (NamedDataSchema) valueSchema);
                }
            }
        }

        private void connectSchemaToResource(VisitContext visitContext, final NamedDataSchema schema) {
            final Node<NamedDataSchema> schemaNode = _relationships.get(schema);
            _dataModels.put(schema.getFullName(), schema);
            final DataSchemaTraverse traveler = new DataSchemaTraverse();
            traveler.traverse(schema, (path, nestedSchema) -> {
                if (nestedSchema instanceof RecordDataSchema && nestedSchema != schema) {
                    final RecordDataSchema nestedRecordSchema = (RecordDataSchema) nestedSchema;
                    _dataModels.put(nestedRecordSchema.getFullName(), nestedRecordSchema);
                    final Node<RecordDataSchema> node = _relationships.get(nestedRecordSchema);
                    schemaNode.addAdjacentNode(node);
                }
            });
            final Node<ResourceSchema> resourceNode = _relationships.get(visitContext.getParentSchema());
            resourceNode.addAdjacentNode(schemaNode);
            schemaNode.addAdjacentNode(resourceNode);
        }

        /**
         * Given a record which includes {@link ServiceErrorsSchema}, scans for service errors and connects the error
         * detail type field (if any) to the resource.
         *
         * @param visitContext visit context
         * @param record record which includes {@link ServiceErrorsSchema}
         */
        private void connectErrorDetailTypeToResource(VisitContext visitContext, RecordTemplate record) {
            final ServiceErrorsSchema serviceErrorsSchema = new ServiceErrorsSchema(record.data());
            if (serviceErrorsSchema.getServiceErrors() != null) {
                for (ServiceErrorSchema serviceErrorSchema : serviceErrorsSchema.getServiceErrors()) {
                    if (serviceErrorSchema.hasErrorDetailType()) {
                        final NamedDataSchema errorDetailTypeSchema = extractSchema(serviceErrorSchema.getErrorDetailType());
                        if (errorDetailTypeSchema != null) {
                            connectSchemaToResource(visitContext, errorDetailTypeSchema);
                        }
                    }
                }
            }
        }
    };
    ResourceSchemaCollection.visitResources(_resourceSchemas.getResources().values(), visitor);
}
Also used : ResourceSchema(com.linkedin.restli.restspec.ResourceSchema) ResourceLevel(com.linkedin.restli.server.ResourceLevel) MapDataSchema(com.linkedin.data.schema.MapDataSchema) ParameterSchema(com.linkedin.restli.restspec.ParameterSchema) BatchFinderSchema(com.linkedin.restli.restspec.BatchFinderSchema) FinderSchema(com.linkedin.restli.restspec.FinderSchema) ActionsSetSchema(com.linkedin.restli.restspec.ActionsSetSchema) StringArray(com.linkedin.data.template.StringArray) IdentifierSchema(com.linkedin.restli.restspec.IdentifierSchema) ServiceErrorsSchema(com.linkedin.restli.restspec.ServiceErrorsSchema) RecordTemplate(com.linkedin.data.template.RecordTemplate) ServiceErrorSchema(com.linkedin.restli.restspec.ServiceErrorSchema) AssociationSchema(com.linkedin.restli.restspec.AssociationSchema) CollectionSchema(com.linkedin.restli.restspec.CollectionSchema) SimpleSchema(com.linkedin.restli.restspec.SimpleSchema) MetadataSchema(com.linkedin.restli.restspec.MetadataSchema) BatchFinderSchema(com.linkedin.restli.restspec.BatchFinderSchema) RestMethodSchema(com.linkedin.restli.restspec.RestMethodSchema) ActionSchema(com.linkedin.restli.restspec.ActionSchema) AssocKeySchema(com.linkedin.restli.restspec.AssocKeySchema) NamedDataSchema(com.linkedin.data.schema.NamedDataSchema) DataSchema(com.linkedin.data.schema.DataSchema) MapDataSchema(com.linkedin.data.schema.MapDataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) NamedDataSchema(com.linkedin.data.schema.NamedDataSchema) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) DataSchemaTraverse(com.linkedin.data.schema.DataSchemaTraverse)

Example 7 with BatchFinderSchema

use of com.linkedin.restli.restspec.BatchFinderSchema in project rest.li by linkedin.

the class ExampleRequestResponseGenerator method batchFinder.

public ExampleRequestResponse batchFinder(String name) {
    BatchFinderSchema batchFinderSchema = _resourceSchema.getBatchFinder(name);
    if (batchFinderSchema == null) {
        throw new IllegalArgumentException("No such batch finder for resource: " + name);
    }
    RecordDataSchema metadataSchema = null;
    if (batchFinderSchema.hasMetadata()) {
        metadataSchema = (RecordDataSchema) RestSpecCodec.textToSchema(batchFinderSchema.getMetadata().getType(), _schemaResolver);
    }
    Request<?> request = buildBatchFinderRequest(batchFinderSchema);
    RestRequest restRequest = buildRequest(request);
    try {
        ServerResourceContext context = new ResourceContextImpl(new PathKeysImpl(), restRequest, new RequestContext());
        DataList criteriaParams = (DataList) context.getStructuredParameter(batchFinderSchema.getBatchParam());
        // Since batchFinder has 2 kinds of responses. One is successful CollectionResponse. The other one is ErrorResponse.
        // When BatchFinderResponseBuilder cannot find a search criteria, it will return an ErrorResponse.
        // To include only one criteria in BatchFinderResult will make the response example diverse.
        // guarantee batchFinder request and response has a same criteria
        AnyRecord batchFinderCriteria = new AnyRecord((DataMap) criteriaParams.get(0));
        return buildRequestResponse(request, buildBatchFinderResult(metadataSchema, batchFinderCriteria), buildResourceMethodDescriptorForBatchFinder(name, batchFinderSchema.getBatchParam()));
    } catch (RestLiSyntaxException e) {
        throw new ExampleGenerationException("Internal error during example generation", e);
    }
}
Also used : AnyRecord(com.linkedin.restli.internal.server.methods.AnyRecord) RestLiSyntaxException(com.linkedin.restli.internal.server.util.RestLiSyntaxException) PathKeysImpl(com.linkedin.restli.internal.server.PathKeysImpl) BatchFinderSchema(com.linkedin.restli.restspec.BatchFinderSchema) DataList(com.linkedin.data.DataList) RestRequest(com.linkedin.r2.message.rest.RestRequest) ServerResourceContext(com.linkedin.restli.internal.server.ServerResourceContext) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) RequestContext(com.linkedin.r2.message.RequestContext) ResourceContextImpl(com.linkedin.restli.internal.server.ResourceContextImpl)

Example 8 with BatchFinderSchema

use of com.linkedin.restli.restspec.BatchFinderSchema in project rest.li by linkedin.

the class ResourceModelEncoder method appendCollections.

private void appendCollections(final CollectionSchema collectionSchema, final ResourceModel resourceModel) {
    ActionSchemaArray actionsArray = new ActionSchemaArray();
    FinderSchemaArray findersArray = new FinderSchemaArray();
    BatchFinderSchemaArray batchFindersArray = new BatchFinderSchemaArray();
    List<ResourceMethodDescriptor> resourceMethodDescriptors = resourceModel.getResourceMethodDescriptors();
    Collections.sort(resourceMethodDescriptors, RESOURCE_METHOD_COMPARATOR);
    for (ResourceMethodDescriptor resourceMethodDescriptor : resourceMethodDescriptors) {
        if (ResourceMethod.ACTION.equals(resourceMethodDescriptor.getType())) {
            // do not apply entity-level actions at collection level or vice-versa
            if (resourceMethodDescriptor.getActionResourceLevel() != ResourceLevel.COLLECTION) {
                continue;
            }
            ActionSchema action = createActionSchema(resourceMethodDescriptor);
            actionsArray.add(action);
        } else if (ResourceMethod.FINDER.equals(resourceMethodDescriptor.getType())) {
            FinderSchema finder = createFinderSchema(resourceMethodDescriptor);
            findersArray.add(finder);
        } else if (ResourceMethod.BATCH_FINDER.equals(resourceMethodDescriptor.getType())) {
            BatchFinderSchema finder = createBatchFinderSchema(resourceMethodDescriptor);
            batchFindersArray.add(finder);
        }
    }
    if (actionsArray.size() > 0) {
        collectionSchema.setActions(actionsArray);
    }
    if (findersArray.size() > 0) {
        collectionSchema.setFinders(findersArray);
    }
    if (batchFindersArray.size() > 0) {
        collectionSchema.setBatchFinders(batchFindersArray);
    }
}
Also used : FinderSchemaArray(com.linkedin.restli.restspec.FinderSchemaArray) BatchFinderSchemaArray(com.linkedin.restli.restspec.BatchFinderSchemaArray) ActionSchemaArray(com.linkedin.restli.restspec.ActionSchemaArray) BatchFinderSchema(com.linkedin.restli.restspec.BatchFinderSchema) BatchFinderSchemaArray(com.linkedin.restli.restspec.BatchFinderSchemaArray) FinderSchema(com.linkedin.restli.restspec.FinderSchema) BatchFinderSchema(com.linkedin.restli.restspec.BatchFinderSchema) ActionSchema(com.linkedin.restli.restspec.ActionSchema)

Example 9 with BatchFinderSchema

use of com.linkedin.restli.restspec.BatchFinderSchema in project rest.li by linkedin.

the class ResourceModelEncoder method createBatchFinderSchema.

private BatchFinderSchema createBatchFinderSchema(ResourceMethodDescriptor resourceMethodDescriptor) {
    BatchFinderSchema batchFinder = new BatchFinderSchema();
    batchFinder.setName(resourceMethodDescriptor.getBatchFinderName());
    String doc = _docsProvider.getMethodDoc(resourceMethodDescriptor.getMethod());
    if (doc != null) {
        batchFinder.setDoc(doc);
    }
    ParameterSchemaArray parameters = createParameters(resourceMethodDescriptor);
    if (parameters.size() > 0) {
        batchFinder.setParameters(parameters);
    }
    StringArray assocKeys = createAssocKeyParameters(resourceMethodDescriptor);
    if (assocKeys.size() > 0) {
        batchFinder.setAssocKeys(assocKeys);
    }
    if (resourceMethodDescriptor.getCollectionCustomMetadataType() != null) {
        batchFinder.setMetadata(createMetadataSchema(resourceMethodDescriptor));
    }
    final DataMap customAnnotation = resourceMethodDescriptor.getCustomAnnotationData();
    String deprecatedDoc = _docsProvider.getMethodDeprecatedTag(resourceMethodDescriptor.getMethod());
    if (deprecatedDoc != null) {
        customAnnotation.put(DEPRECATED_ANNOTATION_NAME, deprecateDocToAnnotationMap(deprecatedDoc));
    }
    if (!customAnnotation.isEmpty()) {
        batchFinder.setAnnotations(new CustomAnnotationContentSchemaMap(customAnnotation));
    }
    if (resourceMethodDescriptor.isPagingSupported()) {
        batchFinder.setPagingSupported(true);
    }
    MaxBatchSizeSchema maxBatchSize = resourceMethodDescriptor.getMaxBatchSize();
    if (maxBatchSize != null) {
        batchFinder.setMaxBatchSize(maxBatchSize);
    }
    appendServiceErrors(batchFinder, resourceMethodDescriptor.getServiceErrors());
    appendSuccessStatuses(batchFinder, resourceMethodDescriptor.getSuccessStatuses());
    BatchFinder batchFinderAnnotation = resourceMethodDescriptor.getMethod().getAnnotation(BatchFinder.class);
    batchFinder.setBatchParam(batchFinderAnnotation.batchParam());
    return batchFinder;
}
Also used : StringArray(com.linkedin.data.template.StringArray) MaxBatchSizeSchema(com.linkedin.restli.restspec.MaxBatchSizeSchema) BatchFinder(com.linkedin.restli.server.annotations.BatchFinder) BatchFinderSchema(com.linkedin.restli.restspec.BatchFinderSchema) ParameterSchemaArray(com.linkedin.restli.restspec.ParameterSchemaArray) CustomAnnotationContentSchemaMap(com.linkedin.restli.restspec.CustomAnnotationContentSchemaMap) DataMap(com.linkedin.data.DataMap)

Aggregations

BatchFinderSchema (com.linkedin.restli.restspec.BatchFinderSchema)9 ActionSchema (com.linkedin.restli.restspec.ActionSchema)5 FinderSchema (com.linkedin.restli.restspec.FinderSchema)5 RestMethodSchema (com.linkedin.restli.restspec.RestMethodSchema)4 DataMap (com.linkedin.data.DataMap)2 ArrayDataSchema (com.linkedin.data.schema.ArrayDataSchema)2 DataSchema (com.linkedin.data.schema.DataSchema)2 NamedDataSchema (com.linkedin.data.schema.NamedDataSchema)2 RecordDataSchema (com.linkedin.data.schema.RecordDataSchema)2 RecordTemplate (com.linkedin.data.template.RecordTemplate)2 StringArray (com.linkedin.data.template.StringArray)2 AssocKeySchema (com.linkedin.restli.restspec.AssocKeySchema)2 AssociationSchema (com.linkedin.restli.restspec.AssociationSchema)2 CollectionSchema (com.linkedin.restli.restspec.CollectionSchema)2 EntitySchema (com.linkedin.restli.restspec.EntitySchema)2 IdentifierSchema (com.linkedin.restli.restspec.IdentifierSchema)2 ParameterSchema (com.linkedin.restli.restspec.ParameterSchema)2 ResourceSchema (com.linkedin.restli.restspec.ResourceSchema)2 ResourceLevel (com.linkedin.restli.server.ResourceLevel)2 DataList (com.linkedin.data.DataList)1