Search in sources :

Example 46 with RecordDataSchema

use of com.linkedin.data.schema.RecordDataSchema in project rest.li by linkedin.

the class ExampleRequestResponseGenerator method finder.

public ExampleRequestResponse finder(String name) {
    FinderSchema finderSchema = _resourceSchema.getFinder(name);
    if (finderSchema == null) {
        throw new IllegalArgumentException("No such finder for resource: " + name);
    }
    RecordDataSchema metadataSchema = null;
    if (finderSchema.hasMetadata()) {
        metadataSchema = (RecordDataSchema) RestSpecCodec.textToSchema(finderSchema.getMetadata().getType(), _schemaResolver);
    }
    return buildRequestResponse(buildFinderRequest(finderSchema), buildFinderResult(metadataSchema), buildResourceMethodDescriptorForFinder(name));
}
Also used : RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) FinderSchema(com.linkedin.restli.restspec.FinderSchema) BatchFinderSchema(com.linkedin.restli.restspec.BatchFinderSchema)

Example 47 with RecordDataSchema

use of com.linkedin.data.schema.RecordDataSchema in project rest.li by linkedin.

the class ExampleRequestResponseGenerator method generateFieldDefValue.

private Object generateFieldDefValue(FieldDef<?> fieldDef) {
    Object value = _dataGenerator.buildData(fieldDef.getName(), fieldDef.getDataSchema());
    DataSchema dereferencedDataSchema = fieldDef.getDataSchema().getDereferencedDataSchema();
    if (!dereferencedDataSchema.isPrimitive()) {
        switch(dereferencedDataSchema.getType()) {
            case FIXED:
                value = new FixedTemplatePlaceholder(value, (FixedDataSchema) dereferencedDataSchema);
                break;
            case ENUM:
                // just use the string value already generated.  Will be coerced by DataTemplateUtil.DynamicEnumCoercer.
                break;
            case ARRAY:
                value = new ArrayTemplatePlaceholder<>((DataList) value, (ArrayDataSchema) dereferencedDataSchema, Object.class);
                break;
            case RECORD:
                value = new RecordTemplatePlaceholder((DataMap) value, (RecordDataSchema) dereferencedDataSchema);
                break;
            case MAP:
                value = new MapTemplatePlaceholder<>((DataMap) value, (MapDataSchema) dereferencedDataSchema, Object.class);
                break;
            case UNION:
                value = new UnionTemplatePlaceholder(value, (UnionDataSchema) dereferencedDataSchema);
                break;
            case TYPEREF:
                throw new IllegalStateException("TYPEREF should not be returned for a dereferenced byte. schema: " + fieldDef.getDataSchema());
            default:
                throw new IllegalStateException("Unrecognized enum value: " + dereferencedDataSchema.getType());
        }
    }
    return value;
}
Also used : MapDataSchema(com.linkedin.data.schema.MapDataSchema) DataMap(com.linkedin.data.DataMap) UnionDataSchema(com.linkedin.data.schema.UnionDataSchema) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) FixedDataSchema(com.linkedin.data.schema.FixedDataSchema) DataSchema(com.linkedin.data.schema.DataSchema) MapDataSchema(com.linkedin.data.schema.MapDataSchema) EnumDataSchema(com.linkedin.data.schema.EnumDataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) DataList(com.linkedin.data.DataList) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) UnionDataSchema(com.linkedin.data.schema.UnionDataSchema) FixedDataSchema(com.linkedin.data.schema.FixedDataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema)

Example 48 with RecordDataSchema

use of com.linkedin.data.schema.RecordDataSchema in project rest.li by linkedin.

the class TestExamplesGenerator method validateActionResponse.

private <T extends RecordTemplate> ValidationResult validateActionResponse(RestResponse response, Class<T> recordClass, ValidationOptions options) throws IOException {
    final DataMap respData = _codec.bytesToMap(response.getEntity().copyBytes());
    final FieldDef<T> responseFieldDef = new FieldDef<>(ActionResponse.VALUE_NAME, recordClass, DataTemplateUtil.getSchema(recordClass));
    final RecordDataSchema recordDataSchema = DynamicRecordMetadata.buildSchema(ActionResponse.class.getName(), Collections.<FieldDef<?>>singletonList(responseFieldDef));
    final ActionResponse<T> actionResp = new ActionResponse<>(respData, responseFieldDef, recordDataSchema);
    final DataSchema recordSchema = DataTemplateUtil.getSchema(recordClass);
    return ValidateDataAgainstSchema.validate(actionResp.getValue().data(), recordSchema, options);
}
Also used : RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) DataSchema(com.linkedin.data.schema.DataSchema) FieldDef(com.linkedin.data.template.FieldDef) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) ActionResponse(com.linkedin.restli.common.ActionResponse) DataMap(com.linkedin.data.DataMap)

Example 49 with RecordDataSchema

use of com.linkedin.data.schema.RecordDataSchema in project rest.li by linkedin.

the class RestLiAnnotationReader method addActionResourceMethod.

/**
 * Add the given action method to the given resource model,  validating the method is a action before adding.
 * @param model provides the model to add the method to.
 * @param method provides the method to add to the model.
 * @throws ResourceConfigException on validation errors.
 */
private static void addActionResourceMethod(final ResourceModel model, final Method method) {
    Action actionAnno = method.getAnnotation(Action.class);
    if (actionAnno == null) {
        return;
    }
    String actionName = actionAnno.name();
    List<Parameter<?>> parameters = getParameters(model, method, ResourceMethod.ACTION);
    Class<?> returnClass = getActionReturnClass(model, method, actionAnno, actionName);
    TyperefDataSchema returnTyperefSchema = getActionTyperefDataSchema(model, actionAnno, actionName);
    validateActionReturnType(model, method, returnClass, returnTyperefSchema);
    if (!Modifier.isPublic(method.getModifiers())) {
        throw new ResourceConfigException(String.format("Resource '%s' contains non-public action method '%s'.", model.getName(), method.getName()));
    }
    RecordDataSchema recordDataSchema = DynamicRecordMetadata.buildSchema(method.getName(), parameters);
    RecordDataSchema actionReturnRecordDataSchema;
    FieldDef<?> returnFieldDef;
    if (returnClass != Void.TYPE) {
        @SuppressWarnings({ "unchecked", "rawtypes" }) FieldDef<?> nonVoidFieldDef = new FieldDef(ActionResponse.VALUE_NAME, returnClass, getDataSchema(returnClass, returnTyperefSchema));
        returnFieldDef = nonVoidFieldDef;
        actionReturnRecordDataSchema = DynamicRecordMetadata.buildSchema(ActionResponse.class.getName(), Collections.singleton((returnFieldDef)));
    } else {
        returnFieldDef = null;
        actionReturnRecordDataSchema = DynamicRecordMetadata.buildSchema(ActionResponse.class.getName(), Collections.<FieldDef<?>>emptyList());
    }
    if (model.getResourceLevel() == ResourceLevel.ENTITY && actionAnno.resourceLevel() == ResourceLevel.COLLECTION) {
        throw new ResourceConfigException(String.format("Resource '%s' is a simple resource, it cannot contain actions at resource level \"COLLECTION\".", model.getName()));
    }
    DataMap annotationsMap = ResourceModelAnnotation.getAnnotationsMap(method.getAnnotations());
    addDeprecatedAnnotation(annotationsMap, method);
    ResourceMethodDescriptor resourceMethodDescriptor = ResourceMethodDescriptor.createForAction(method, parameters, actionName, getActionResourceLevel(actionAnno, model), returnFieldDef, actionReturnRecordDataSchema, actionAnno.readOnly(), recordDataSchema, getInterfaceType(method), annotationsMap);
    addServiceErrors(resourceMethodDescriptor, method);
    addSuccessStatuses(resourceMethodDescriptor, method);
    model.addResourceMethodDescriptor(resourceMethodDescriptor);
}
Also used : Action(com.linkedin.restli.server.annotations.Action) DataMap(com.linkedin.data.DataMap) FieldDef(com.linkedin.data.template.FieldDef) TyperefDataSchema(com.linkedin.data.schema.TyperefDataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) ResourceConfigException(com.linkedin.restli.server.ResourceConfigException)

Example 50 with RecordDataSchema

use of com.linkedin.data.schema.RecordDataSchema in project rest.li by linkedin.

the class ActionResponseBuilder method buildRestLiResponseData.

/**
 * {@inheritDoc}
 *
 * @param result The result for a Rest.li ACTION method. It can be the return value for the ACTION itself, or the
 *               return value wrapped in an {@link ActionResult}.
 */
@Override
public RestLiResponseData<ActionResponseEnvelope> buildRestLiResponseData(Request request, RoutingResult routingResult, Object result, Map<String, String> headers, List<HttpCookie> cookies) {
    final Object value;
    final HttpStatus status;
    if (result instanceof ActionResult) {
        final ActionResult<?> actionResult = (ActionResult<?>) result;
        value = actionResult.getValue();
        status = actionResult.getStatus();
        if (status == null) {
            throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. Null HttpStatus inside of an ActionResult returned by the resource method: " + routingResult.getResourceMethod());
        }
        // When it has an ActionResult<Void> type response, it should return null but not empty body record
        if (routingResult.getResourceMethod().getActionReturnType() == Void.TYPE) {
            return new RestLiResponseDataImpl<>(new ActionResponseEnvelope(status, null), headers, cookies);
        }
    } else {
        // when value == null and return type is void, it is handled outside in RestLiResponseHandler
        value = result;
        status = HttpStatus.S_200_OK;
    }
    RecordDataSchema actionReturnRecordDataSchema = routingResult.getResourceMethod().getActionReturnRecordDataSchema();
    final Object actionResponseValue;
    if (value != null && RecordTemplate.class.isAssignableFrom(value.getClass()) && routingResult.getContext().isFillInDefaultsRequested()) {
        RecordTemplate actionResponseRecordTemplate = (RecordTemplate) value;
        DataMap dataMap = actionResponseRecordTemplate.data();
        dataMap = (DataMap) ResponseUtils.fillInDataDefault(actionResponseRecordTemplate.schema(), dataMap);
        Object valueWithDefault = null;
        try {
            valueWithDefault = (Object) value.getClass().getConstructor(DataMap.class).newInstance(dataMap);
        } catch (Exception e) {
            throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected error encountered. Can not create return value class " + value.getClass().getSimpleName() + " with default filled  inside of an ActionResult returned by the resource method: " + routingResult.getResourceMethod());
        }
        actionResponseValue = valueWithDefault;
    } else {
        actionResponseValue = value;
    }
    @SuppressWarnings("unchecked") FieldDef<Object> actionReturnFieldDef = (FieldDef<Object>) routingResult.getResourceMethod().getActionReturnFieldDef();
    final ActionResponse<?> actionResponse = new ActionResponse<>(actionResponseValue, actionReturnFieldDef, actionReturnRecordDataSchema);
    return new RestLiResponseDataImpl<>(new ActionResponseEnvelope(status, actionResponse), headers, cookies);
}
Also used : HttpStatus(com.linkedin.restli.common.HttpStatus) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) ActionResponse(com.linkedin.restli.common.ActionResponse) DataMap(com.linkedin.data.DataMap) FieldDef(com.linkedin.data.template.FieldDef) ActionResult(com.linkedin.restli.server.ActionResult) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RecordTemplate(com.linkedin.data.template.RecordTemplate) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema)

Aggregations

RecordDataSchema (com.linkedin.data.schema.RecordDataSchema)106 DataMap (com.linkedin.data.DataMap)43 Test (org.testng.annotations.Test)43 DataSchema (com.linkedin.data.schema.DataSchema)40 UnionDataSchema (com.linkedin.data.schema.UnionDataSchema)32 ArrayDataSchema (com.linkedin.data.schema.ArrayDataSchema)28 MapDataSchema (com.linkedin.data.schema.MapDataSchema)26 TyperefDataSchema (com.linkedin.data.schema.TyperefDataSchema)25 NamedDataSchema (com.linkedin.data.schema.NamedDataSchema)20 EnumDataSchema (com.linkedin.data.schema.EnumDataSchema)19 ArrayList (java.util.ArrayList)18 FixedDataSchema (com.linkedin.data.schema.FixedDataSchema)14 Name (com.linkedin.data.schema.Name)14 Map (java.util.Map)10 Schema (org.apache.avro.Schema)10 DataList (com.linkedin.data.DataList)9 GenericRecord (org.apache.avro.generic.GenericRecord)9 ValidateDataAgainstSchema (com.linkedin.data.schema.validation.ValidateDataAgainstSchema)8 HashMap (java.util.HashMap)8 FieldDef (com.linkedin.data.template.FieldDef)7