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);
}
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);
}
}
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);
}
}
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;
}
Aggregations