use of com.linkedin.data.schema.RecordDataSchema in project rest.li by linkedin.
the class ExtensionSchemaValidationCmdLineApp method parseAndValidateExtensionSchemas.
static void parseAndValidateExtensionSchemas(String resolverPath, File inputDir) throws IOException, InvalidExtensionSchemaException {
// Parse each extension schema and validate it
Iterator<File> iterator = FileUtils.iterateFiles(inputDir, new String[] { PDL }, true);
DataSchemaResolver resolver = MultiFormatDataSchemaResolver.withBuiltinFormats(resolverPath);
while (iterator.hasNext()) {
File inputFile = iterator.next();
PdlSchemaParser parser = new PdlSchemaParser(resolver);
parser.parse(new FileInputStream(inputFile));
if (parser.hasError()) {
throw new InvalidExtensionSchemaException(parser.errorMessage());
}
List<DataSchema> topLevelDataSchemas = parser.topLevelDataSchemas();
if (topLevelDataSchemas == null || topLevelDataSchemas.isEmpty() || topLevelDataSchemas.size() > 1) {
throw new InvalidExtensionSchemaException("Could not parse extension schema : " + inputFile.getAbsolutePath());
}
DataSchema topLevelDataSchema = topLevelDataSchemas.get(0);
if (!(topLevelDataSchema instanceof NamedDataSchema)) {
throw new InvalidExtensionSchemaException("Invalid extension schema : " + inputFile.getAbsolutePath() + ", the schema is not a named schema.");
}
if (!((NamedDataSchema) topLevelDataSchema).getName().endsWith(EXTENSIONS_SUFFIX)) {
throw new InvalidExtensionSchemaException("Invalid extension schema name: '" + ((NamedDataSchema) topLevelDataSchema).getName() + "'. The name of the extension schema must be <baseSchemaName> + 'Extensions'");
}
List<NamedDataSchema> includes = ((RecordDataSchema) topLevelDataSchema).getInclude();
if (includes.size() != 1) {
throw new InvalidExtensionSchemaException("The extension schema: '" + ((NamedDataSchema) topLevelDataSchema).getName() + "' should include and only include the base schema");
}
NamedDataSchema includeSchema = includes.get(0);
if (!((NamedDataSchema) topLevelDataSchema).getName().startsWith(includeSchema.getName())) {
throw new InvalidExtensionSchemaException("Invalid extension schema name: '" + ((NamedDataSchema) topLevelDataSchema).getName() + "'. The name of the extension schema must be baseSchemaName: '" + includeSchema.getName() + "' + 'Extensions");
}
List<RecordDataSchema.Field> extensionSchemaFields = ((RecordDataSchema) topLevelDataSchema).getFields().stream().filter(f -> !((RecordDataSchema) topLevelDataSchema).isFieldFromIncludes(f)).collect(Collectors.toList());
checkExtensionSchemaFields(extensionSchemaFields);
}
}
use of com.linkedin.data.schema.RecordDataSchema in project rest.li by linkedin.
the class TestTemplateSpecGenerator method testCustomInfoForRecordFields.
@Test(dataProvider = "customTypeDataForRecord")
public void testCustomInfoForRecordFields(final List<DataSchema> customTypedSchemas) {
final List<RecordDataSchema.Field> fields = customTypedSchemas.stream().map(RecordDataSchema.Field::new).peek(field -> field.setName("field_" + _uniqueNumberGenerator.getAndIncrement(), null)).collect(Collectors.toList());
final RecordDataSchema record = new RecordDataSchema(new Name(INPUT_SCHEMA_NAME), RecordDataSchema.RecordType.RECORD);
record.setFields(fields, null);
final TemplateSpecGenerator generator = new TemplateSpecGenerator(_resolver);
final RecordTemplateSpec spec = (RecordTemplateSpec) generator.generate(record, _location);
for (int i = 0; i < customTypedSchemas.size(); ++i) {
Assert.assertNotNull(spec.getFields().get(i).getCustomInfo());
Assert.assertEquals(spec.getFields().get(i).getCustomInfo().getCustomClass().getClassName(), CustomTypeUtil.getJavaCustomTypeClassNameFromSchema((TyperefDataSchema) customTypedSchemas.get(i)));
}
}
use of com.linkedin.data.schema.RecordDataSchema in project rest.li by linkedin.
the class RestLiResponseException method getErrorDetailsRecord.
/**
* Gets the error details as a typed record based on the error detail type. {@code null} will be returned if
* there are no error details, if there is no error detail type, or if no class is found that corresponds with
* the error detail type.
*
* @param <T> the error detail type specified in the {@link ErrorResponse}
* @return the error details as a typed record, or null
*/
@SuppressWarnings({ "unchecked", "ConstantConditions" })
public <T extends RecordTemplate> T getErrorDetailsRecord() {
if (_errorResponse.hasErrorDetails() && _errorResponse.hasErrorDetailType()) {
String type = _errorResponse.getErrorDetailType();
try {
Class<?> typeClass = Class.forName(type);
if (RecordTemplate.class.isAssignableFrom(typeClass)) {
Class<? extends RecordTemplate> recordType = typeClass.asSubclass(RecordTemplate.class);
RecordDataSchema schema = (RecordDataSchema) DataTemplateUtil.getSchema(typeClass);
return (T) DataTemplateUtil.wrap(_errorResponse.getErrorDetails().data(), schema, recordType);
}
} catch (ClassNotFoundException e) {
return null;
}
}
return null;
}
use of com.linkedin.data.schema.RecordDataSchema in project rest.li by linkedin.
the class GetResponseBuilder method buildRestLiResponseData.
/**
* {@inheritDoc}
*
* @param result The result of a Rest.li GET method. It can be the entity itself, or the entity wrapped in a
* {@link GetResult}.
*/
@Override
public RestLiResponseData<GetResponseEnvelope> buildRestLiResponseData(Request request, RoutingResult routingResult, Object result, Map<String, String> headers, List<HttpCookie> cookies) {
final RecordTemplate record;
final HttpStatus status;
if (result instanceof GetResult) {
final GetResult<?> getResult = (GetResult<?>) result;
record = getResult.getValue();
status = getResult.getStatus();
} else {
record = (RecordTemplate) result;
status = HttpStatus.S_200_OK;
}
final ResourceContext resourceContext = routingResult.getContext();
DataMap rawData = record.data();
RecordDataSchema schema = record.schema();
if (resourceContext.isFillInDefaultsRequested()) {
rawData = (DataMap) ResponseUtils.fillInDataDefault(schema, rawData);
}
TimingContextUtil.beginTiming(resourceContext.getRawRequestContext(), FrameworkTimingKeys.SERVER_RESPONSE_RESTLI_PROJECTION_APPLY.key());
final DataMap data = RestUtils.projectFields(rawData, resourceContext);
TimingContextUtil.endTiming(resourceContext.getRawRequestContext(), FrameworkTimingKeys.SERVER_RESPONSE_RESTLI_PROJECTION_APPLY.key());
return new RestLiResponseDataImpl<>(new GetResponseEnvelope(status, new AnyRecord(data)), headers, cookies);
}
use of com.linkedin.data.schema.RecordDataSchema in project rest.li by linkedin.
the class ResponseUtils method fillInDefaultOnRecord.
private static DataMap fillInDefaultOnRecord(RecordDataSchema schema, DataMap dataMap) throws CloneNotSupportedException {
DataMap dataWithDefault = dataMap.clone();
for (RecordDataSchema.Field field : schema.getFields()) {
if (dataMap.containsKey(field.getName()) || field.getDefault() != null) {
Object fieldData = dataMap.containsKey(field.getName()) ? dataMap.get(field.getName()) : field.getDefault();
CheckedUtil.putWithoutChecking(dataWithDefault, field.getName(), fillInDataDefault(field.getType(), fieldData));
}
}
return dataWithDefault;
}
Aggregations