use of org.talend.sdk.component.server.front.model.error.ErrorPayload in project component-runtime by Talend.
the class ComponentResource method icon.
/**
* Returns a particular component icon in raw bytes.
*
* @param id the component identifier.
* @return the component icon in binary form.
*/
@GET
@Path("icon/{id}")
public Response icon(@PathParam("id") final String id) {
// todo: add caching if SvgIconResolver becomes used a lot - not the case ATM
final ComponentFamilyMeta.BaseMeta<Object> meta = componentDao.findById(id);
if (meta == null) {
return Response.status(Response.Status.NOT_FOUND).entity(new ErrorPayload(ErrorDictionary.COMPONENT_MISSING, "No component for identifier: " + id)).type(APPLICATION_JSON_TYPE).build();
}
final Optional<Container> plugin = manager.findPlugin(meta.getParent().getPlugin());
if (!plugin.isPresent()) {
return Response.status(Response.Status.NOT_FOUND).entity(new ErrorPayload(ErrorDictionary.PLUGIN_MISSING, "No plugin '" + meta.getParent().getPlugin() + "' for identifier: " + id)).type(APPLICATION_JSON_TYPE).build();
}
final IconResolver.Icon iconContent = iconResolver.resolve(plugin.get().getLoader(), meta.getIcon());
if (iconContent == null) {
return Response.status(Response.Status.NOT_FOUND).entity(new ErrorPayload(ErrorDictionary.ICON_MISSING, "No icon for identifier: " + id)).type(APPLICATION_JSON_TYPE).build();
}
return Response.ok(iconContent.getBytes()).type(iconContent.getType()).build();
}
use of org.talend.sdk.component.server.front.model.error.ErrorPayload in project component-runtime by Talend.
the class DocumentationResource method getDocumentation.
/**
* Returns an asciidoctor version of the documentation for the component represented by its identifier `id`.
*
* Format can be either asciidoc or html - if not it will fallback on asciidoc - and if html is selected you get
* a partial document.
*
* IMPORTANT: it is recommended to use asciidoc format and handle the conversion on your side if you can,
* the html flavor handles a limited set of the asciidoc syntax only like plain arrays, paragraph and titles.
*
* The documentation will likely be the family documentation but you can use anchors to access a particular
* component (_componentname_inlowercase).
*
* @param id the component identifier.
* @param language the expected language for the documentation (default to en if not found).
* @param format the expected format (asciidoc or html).
* @return the documentation for that component.
*/
@GET
@Path("component/{id}")
@Produces(MediaType.APPLICATION_JSON)
public DocumentationContent getDocumentation(@PathParam("id") final String id, @QueryParam("language") @DefaultValue("en") final String language, @QueryParam("format") @DefaultValue("asciidoc") final String format) {
final Locale locale = localeMapper.mapLocale(language);
final Container container = ofNullable(componentDao.findById(id)).map(meta -> manager.findPlugin(meta.getParent().getPlugin()).orElseThrow(() -> new WebApplicationException(Response.status(NOT_FOUND).entity(new ErrorPayload(ErrorDictionary.PLUGIN_MISSING, "No plugin '" + meta.getParent().getPlugin() + "'")).build()))).orElseThrow(() -> new WebApplicationException(Response.status(NOT_FOUND).entity(new ErrorPayload(ErrorDictionary.COMPONENT_MISSING, "No component '" + id + "'")).build()));
// rendering to html can be slow so do it lazily and once
DocumentationCache cache = container.get(DocumentationCache.class);
if (cache == null) {
synchronized (container) {
cache = container.get(DocumentationCache.class);
if (cache == null) {
cache = new DocumentationCache();
container.set(DocumentationCache.class, cache);
}
}
}
return cache.documentations.computeIfAbsent(new DocKey(id, language, format), key -> {
// todo: handle i18n properly, for now just fallback on not suffixed version and assume the dev put it
// in the comp
final String content = Stream.of("documentation_" + locale.getLanguage() + ".adoc", "documentation_" + language + ".adoc", "documentation.adoc").map(name -> container.getLoader().getResource("TALEND-INF/" + name)).filter(Objects::nonNull).findFirst().map(url -> {
try (final BufferedReader stream = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8))) {
return stream.lines().collect(joining("\n"));
} catch (final IOException e) {
throw new WebApplicationException(Response.status(INTERNAL_SERVER_ERROR).entity(new ErrorPayload(ErrorDictionary.UNEXPECTED, e.getMessage())).build());
}
}).map(value -> {
switch(format) {
case "html":
case "html5":
return adoc.toHtml(value);
case "asciidoc":
case "adoc":
default:
return value;
}
}).orElseThrow(() -> new WebApplicationException(Response.status(NOT_FOUND).entity(new ErrorPayload(ErrorDictionary.COMPONENT_MISSING, "No component '" + id + "'")).build()));
return new DocumentationContent(format, content);
});
}
use of org.talend.sdk.component.server.front.model.error.ErrorPayload in project component-runtime by Talend.
the class ExecutionResource method read.
/**
* Read inputs from an instance of mapper. The number of returned records if enforced to be limited to 1000.
* The format is a JSON based format where each like is a json record.
*
* @param family the component family.
* @param component the component name.
* @param size the maximum number of records to read.
* @param configuration the component configuration as key/values.
*/
@POST
@Deprecated
@Produces("talend/stream")
@Path("read/{family}/{component}")
public void read(@Suspended final AsyncResponse response, @Context final Providers providers, @PathParam("family") final String family, @PathParam("component") final String component, @QueryParam("size") @DefaultValue("50") final long size, final Map<String, String> configuration) {
final long maxSize = Math.min(size, MAX_RECORDS);
response.setTimeoutHandler(asyncResponse -> log.warn("Timeout on dataset retrieval"));
response.setTimeout(appConfiguration.datasetRetrieverTimeout(), SECONDS);
executorService.submit(() -> {
final Optional<Mapper> mapperOptional = manager.findMapper(family, component, getConfigComponentVersion(configuration), configuration);
if (!mapperOptional.isPresent()) {
response.resume(new WebApplicationException(Response.status(BAD_REQUEST).entity(new ErrorPayload(COMPONENT_MISSING, "Didn't find the input component")).build()));
return;
}
final Mapper mapper = mapperOptional.get();
mapper.start();
try {
final Input input = mapper.create();
try {
input.start();
response.resume((StreamingOutput) output -> {
Object data;
int current = 0;
while (current++ < maxSize && (data = input.next()) != null) {
if (CharSequence.class.isInstance(data) || Number.class.isInstance(data) || Boolean.class.isInstance(data)) {
final PrimitiveWrapper wrapper = new PrimitiveWrapper();
wrapper.setValue(data);
data = wrapper;
}
inlineStreamingMapper.toJson(data, output);
output.write(EOL);
}
});
} finally {
input.stop();
}
} finally {
mapper.stop();
}
});
}
use of org.talend.sdk.component.server.front.model.error.ErrorPayload in project component-runtime by Talend.
the class ExecutionResource method write.
/**
* Sends records using a processor instance. Note that the processor should have only an input.
* Behavior for other processors is undefined.
* The input format is a JSON based format where each like is a json record - same as for the symmetric endpoint.
*
* @param family the component family.
* @param component the component name.
* @param chunkSize the bundle size (chunk size).
*/
@POST
@Deprecated
@Consumes("talend/stream")
@Produces(MediaType.APPLICATION_JSON)
@Path("write/{family}/{component}")
public void write(@Suspended final AsyncResponse response, @Context final Providers providers, @PathParam("family") final String family, @PathParam("component") final String component, @QueryParam("group-size") @DefaultValue("50") final long chunkSize, final InputStream stream) {
response.setTimeoutHandler(asyncResponse -> log.warn("Timeout on dataset retrieval"));
response.setTimeout(appConfiguration.datasetRetrieverTimeout(), SECONDS);
executorService.submit(() -> {
Processor processor = null;
final WriteStatistics statistics = new WriteStatistics(0);
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
String line = reader.readLine();
if (line == null || line.trim().isEmpty()) {
response.resume(new WebApplicationException(Response.status(BAD_REQUEST).entity(new ErrorPayload(ACTION_ERROR, "No configuration sent")).build()));
return;
}
final JsonObject configuration = inlineStreamingMapper.fromJson(line, JsonObject.class);
final Map<String, String> config = convertConfig(configuration);
final Optional<Processor> processorOptional = manager.findProcessor(family, component, getConfigComponentVersion(config), config);
if (!processorOptional.isPresent()) {
response.resume(new WebApplicationException(Response.status(BAD_REQUEST).entity(new ErrorPayload(COMPONENT_MISSING, "Didn't find the output component")).build()));
return;
}
processor = processorOptional.get();
processor.start();
int groupCount = 0;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (!line.isEmpty()) {
final JsonObject object = inlineStreamingMapper.fromJson(line, JsonObject.class);
if (groupCount == 0) {
processor.beforeGroup();
}
groupCount++;
processor.onNext(name -> {
if (!Branches.DEFAULT_BRANCH.equals(name)) {
throw new IllegalArgumentException("Can't access branch '" + name + "' from component " + family + "#" + name);
}
return inlineStreamingMapper.fromJson(inlineStreamingMapper.toJson(object), JsonObject.class);
}, mockOutputFactory);
statistics.setCount(statistics.getCount() + 1);
if (groupCount == chunkSize) {
processor.afterGroup(mockOutputFactory);
}
}
}
} catch (final Exception e) {
response.resume(new WebApplicationException(Response.status(BAD_REQUEST).entity(new ErrorPayload(ACTION_ERROR, "Didn't find the input component")).build()));
} finally {
ofNullable(processor).ifPresent(Processor::stop);
}
response.resume(statistics);
});
}
use of org.talend.sdk.component.server.front.model.error.ErrorPayload in project component-runtime by Talend.
the class CommandSecurityProvider method filter.
@Override
public void filter(final ContainerRequestContext requestContext) throws IOException {
if (Boolean.TRUE.equals(request.getAttribute(SKIP))) {
return;
}
final OnCommand onCommand = new OnCommand(resourceInfo.getResourceClass(), resourceInfo.getResourceMethod());
onConnectionEvent.fire(onCommand);
if (!onCommand.isValid()) {
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity(new ErrorPayload(UNAUTHORIZED, "Invalid command credentials")).type(APPLICATION_JSON_TYPE).build());
}
}
Aggregations