Search in sources :

Example 6 with ErrorPayload

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();
}
Also used : ErrorPayload(org.talend.sdk.component.server.front.model.error.ErrorPayload) Container(org.talend.sdk.component.container.Container) IconResolver(org.talend.sdk.component.server.service.IconResolver) ComponentFamilyMeta(org.talend.sdk.component.runtime.manager.ComponentFamilyMeta) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Example 7 with ErrorPayload

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);
    });
}
Also used : Locale(java.util.Locale) PathParam(javax.ws.rs.PathParam) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) Path(javax.ws.rs.Path) ConcurrentMap(java.util.concurrent.ConcurrentMap) Inject(javax.inject.Inject) MediaType(javax.ws.rs.core.MediaType) DocumentationContent(org.talend.sdk.component.server.front.model.DocumentationContent) LocaleMapper(org.talend.sdk.component.server.service.LocaleMapper) QueryParam(javax.ws.rs.QueryParam) Locale(java.util.Locale) DefaultValue(javax.ws.rs.DefaultValue) Container(org.talend.sdk.component.container.Container) AsciidoctorService(org.talend.sdk.component.server.service.AsciidoctorService) Optional.ofNullable(java.util.Optional.ofNullable) INTERNAL_SERVER_ERROR(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR) NOT_FOUND(javax.ws.rs.core.Response.Status.NOT_FOUND) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IOException(java.io.IOException) InputStreamReader(java.io.InputStreamReader) Collectors.joining(java.util.stream.Collectors.joining) StandardCharsets(java.nio.charset.StandardCharsets) ErrorDictionary(org.talend.sdk.component.server.front.model.ErrorDictionary) ErrorPayload(org.talend.sdk.component.server.front.model.error.ErrorPayload) Objects(java.util.Objects) Slf4j(lombok.extern.slf4j.Slf4j) Stream(java.util.stream.Stream) Response(javax.ws.rs.core.Response) ComponentDao(org.talend.sdk.component.server.dao.ComponentDao) Data(lombok.Data) WebApplicationException(javax.ws.rs.WebApplicationException) ApplicationScoped(javax.enterprise.context.ApplicationScoped) BufferedReader(java.io.BufferedReader) ComponentManager(org.talend.sdk.component.runtime.manager.ComponentManager) WebApplicationException(javax.ws.rs.WebApplicationException) InputStreamReader(java.io.InputStreamReader) IOException(java.io.IOException) DocumentationContent(org.talend.sdk.component.server.front.model.DocumentationContent) Container(org.talend.sdk.component.container.Container) ErrorPayload(org.talend.sdk.component.server.front.model.error.ErrorPayload) Objects(java.util.Objects) BufferedReader(java.io.BufferedReader) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Example 8 with ErrorPayload

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();
        }
    });
}
Also used : PrimitiveWrapper(org.talend.sdk.component.server.front.model.execution.PrimitiveWrapper) Produces(javax.ws.rs.Produces) Path(javax.ws.rs.Path) BAD_FORMAT(org.talend.sdk.component.server.front.model.ErrorDictionary.BAD_FORMAT) PreDestroy(javax.annotation.PreDestroy) MediaType(javax.ws.rs.core.MediaType) JsonNumber(javax.json.JsonNumber) QueryParam(javax.ws.rs.QueryParam) Collectors.toMap(java.util.stream.Collectors.toMap) Consumes(javax.ws.rs.Consumes) Map(java.util.Map) DefaultValue(javax.ws.rs.DefaultValue) BAD_REQUEST(javax.ws.rs.core.Response.Status.BAD_REQUEST) JsonObject(javax.json.JsonObject) JsonbBuilder(javax.json.bind.JsonbBuilder) Context(javax.ws.rs.core.Context) Providers(javax.ws.rs.ext.Providers) AsyncResponse(javax.ws.rs.container.AsyncResponse) StreamingOutput(javax.ws.rs.core.StreamingOutput) Processor(org.talend.sdk.component.runtime.output.Processor) Suspended(javax.ws.rs.container.Suspended) StandardCharsets(java.nio.charset.StandardCharsets) ErrorPayload(org.talend.sdk.component.server.front.model.error.ErrorPayload) OutputEmitter(org.talend.sdk.component.api.processor.OutputEmitter) Branches(org.talend.sdk.component.runtime.output.Branches) Slf4j(lombok.extern.slf4j.Slf4j) Response(javax.ws.rs.core.Response) PostConstruct(javax.annotation.PostConstruct) Optional(java.util.Optional) WebApplicationException(javax.ws.rs.WebApplicationException) ApplicationScoped(javax.enterprise.context.ApplicationScoped) ACTION_ERROR(org.talend.sdk.component.server.front.model.ErrorDictionary.ACTION_ERROR) WriteStatistics(org.talend.sdk.component.server.front.model.execution.WriteStatistics) PathParam(javax.ws.rs.PathParam) OutputFactory(org.talend.sdk.component.runtime.output.OutputFactory) Inject(javax.inject.Inject) ComponentServerConfiguration(org.talend.sdk.component.server.configuration.ComponentServerConfiguration) Input(org.talend.sdk.component.runtime.input.Input) ExecutorService(java.util.concurrent.ExecutorService) POST(javax.ws.rs.POST) Optional.ofNullable(java.util.Optional.ofNullable) COMPONENT_MISSING(org.talend.sdk.component.server.front.model.ErrorDictionary.COMPONENT_MISSING) InputStreamReader(java.io.InputStreamReader) JsonString(javax.json.JsonString) Mapper(org.talend.sdk.component.runtime.input.Mapper) Jsonb(javax.json.bind.Jsonb) BufferedReader(java.io.BufferedReader) ComponentManager(org.talend.sdk.component.runtime.manager.ComponentManager) SECONDS(java.util.concurrent.TimeUnit.SECONDS) InputStream(java.io.InputStream) Mapper(org.talend.sdk.component.runtime.input.Mapper) PrimitiveWrapper(org.talend.sdk.component.server.front.model.execution.PrimitiveWrapper) ErrorPayload(org.talend.sdk.component.server.front.model.error.ErrorPayload) Input(org.talend.sdk.component.runtime.input.Input) WebApplicationException(javax.ws.rs.WebApplicationException) JsonNumber(javax.json.JsonNumber) JsonObject(javax.json.JsonObject) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces)

Example 9 with ErrorPayload

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);
    });
}
Also used : Processor(org.talend.sdk.component.runtime.output.Processor) InputStreamReader(java.io.InputStreamReader) WebApplicationException(javax.ws.rs.WebApplicationException) JsonObject(javax.json.JsonObject) JsonString(javax.json.JsonString) WebApplicationException(javax.ws.rs.WebApplicationException) ErrorPayload(org.talend.sdk.component.server.front.model.error.ErrorPayload) WriteStatistics(org.talend.sdk.component.server.front.model.execution.WriteStatistics) BufferedReader(java.io.BufferedReader) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces)

Example 10 with ErrorPayload

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());
    }
}
Also used : OnCommand(org.talend.sdk.component.server.service.security.event.OnCommand) ErrorPayload(org.talend.sdk.component.server.front.model.error.ErrorPayload)

Aggregations

ErrorPayload (org.talend.sdk.component.server.front.model.error.ErrorPayload)10 Path (javax.ws.rs.Path)7 GET (javax.ws.rs.GET)5 WebApplicationException (javax.ws.rs.WebApplicationException)5 Container (org.talend.sdk.component.container.Container)5 Produces (javax.ws.rs.Produces)4 Response (javax.ws.rs.core.Response)4 ComponentFamilyMeta (org.talend.sdk.component.runtime.manager.ComponentFamilyMeta)4 BufferedReader (java.io.BufferedReader)3 InputStreamReader (java.io.InputStreamReader)3 Locale (java.util.Locale)3 Optional.ofNullable (java.util.Optional.ofNullable)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 ApplicationScoped (javax.enterprise.context.ApplicationScoped)3 Inject (javax.inject.Inject)3 Consumes (javax.ws.rs.Consumes)3 DefaultValue (javax.ws.rs.DefaultValue)3 POST (javax.ws.rs.POST)3 PathParam (javax.ws.rs.PathParam)3 QueryParam (javax.ws.rs.QueryParam)3