001/** 002 * Copyright (C) 2006-2025 Talend Inc. - www.talend.com 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.talend.sdk.component.server.api; 017 018import static javax.ws.rs.core.MediaType.APPLICATION_JSON; 019import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM; 020import static org.eclipse.microprofile.openapi.annotations.enums.ParameterIn.PATH; 021import static org.eclipse.microprofile.openapi.annotations.enums.ParameterIn.QUERY; 022import static org.eclipse.microprofile.openapi.annotations.enums.SchemaType.OBJECT; 023import static org.eclipse.microprofile.openapi.annotations.enums.SchemaType.STRING; 024 025import java.util.Map; 026 027import javax.ws.rs.Consumes; 028import javax.ws.rs.DefaultValue; 029import javax.ws.rs.GET; 030import javax.ws.rs.POST; 031import javax.ws.rs.Path; 032import javax.ws.rs.PathParam; 033import javax.ws.rs.Produces; 034import javax.ws.rs.QueryParam; 035import javax.ws.rs.core.MediaType; 036import javax.ws.rs.core.Response; 037import javax.ws.rs.core.StreamingOutput; 038 039import org.eclipse.microprofile.openapi.annotations.Operation; 040import org.eclipse.microprofile.openapi.annotations.media.Content; 041import org.eclipse.microprofile.openapi.annotations.media.Schema; 042import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; 043import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody; 044import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; 045import org.eclipse.microprofile.openapi.annotations.tags.Tag; 046import org.talend.sdk.component.server.front.model.ComponentDetailList; 047import org.talend.sdk.component.server.front.model.ComponentIndices; 048import org.talend.sdk.component.server.front.model.Dependencies; 049import org.talend.sdk.component.server.front.model.error.ErrorPayload; 050 051@Path("component") 052@Consumes(MediaType.APPLICATION_JSON) 053@Produces(MediaType.APPLICATION_JSON) 054@Tag(name = "Component", description = "Endpoints related to component metadata access.") 055public interface ComponentResource { 056 057 String IMAGE_SVG_XML = "image/svg+xml"; 058 059 @GET 060 @Path("dependencies") 061 @Operation(description = "Returns a list of dependencies for the given components. " 062 + "IMPORTANT: don't forget to add the component itself since it will not be part of the dependencies." 063 + "Then you can use /dependency/{id} to download the binary.") 064 @APIResponse(responseCode = "200", 065 description = "The list of dependencies per component.", 066 content = @Content(mediaType = APPLICATION_JSON)) 067 Dependencies getDependencies(@QueryParam("identifier") @Parameter(name = "identifier", 068 description = "The identifier id to request. Repeat this parameter to request more than one element.", 069 in = QUERY) String[] ids); 070 071 @GET 072 @Path("dependency/{id}") 073 @Produces(MediaType.APPLICATION_OCTET_STREAM) 074 @Operation(description = "Return a binary of the dependency represented by `id`. " 075 + "It can be maven coordinates for dependencies or a component id.") 076 @APIResponse(responseCode = "200", 077 description = "The dependency binary (jar).", 078 content = @Content(mediaType = APPLICATION_OCTET_STREAM)) 079 @APIResponse(responseCode = "404", 080 description = "If the plugin is missing, payload will be an ErrorPayload with the code PLUGIN_MISSING.", 081 content = @Content(mediaType = APPLICATION_JSON, 082 schema = @Schema(type = OBJECT, implementation = ErrorPayload.class))) 083 StreamingOutput getDependency(@PathParam("id") @Parameter(name = "id", 084 description = "Dependency identifier for component/configurationType or maven coordinate. \n" + 085 "Example: `/api/v1/component/dependency/org.apache.commons:commons-lang3:jar:3.12.0`.", 086 in = PATH) String id); 087 088 @GET 089 @Path("index") 090 @Operation(operationId = "getComponentIndex", 091 description = "Returns the list of available components.") 092 @APIResponse(responseCode = "200", 093 description = "The index of available components.", 094 content = @Content(mediaType = APPLICATION_OCTET_STREAM)) 095 ComponentIndices getIndex( 096 @QueryParam("language") @DefaultValue("en") @Parameter(name = "language", 097 description = "Response language in i18n format.", in = QUERY, 098 schema = @Schema(type = STRING, defaultValue = "en")) String language, 099 @QueryParam("includeIconContent") @DefaultValue("false") @Parameter(name = "includeIconContent", 100 description = "Should the icon binary format be included in the payload. " + 101 "Default is `false`.", 102 in = QUERY, 103 schema = @Schema(type = STRING, defaultValue = "en")) boolean includeIconContent, 104 @QueryParam("q") @Parameter(name = "q", 105 description = "Query in simple query language to filter components. " 106 + "It provides access to the component `plugin`, `name`, `id` and `metadata` of the first configuration property. " 107 + "Ex: `(id = AYETAE658349453) AND (metadata[configurationtype::type] = dataset) AND (plugin = jdbc-component) AND " 108 + "(name = input)`.", 109 in = QUERY, schema = @Schema(type = STRING)) String query, 110 @QueryParam("theme") @Parameter(name = "theme", 111 description = "Theme selector (light/dark). Defaults to light.") String theme); 112 113 @GET 114 @Path("icon/family/{id}") 115 @Produces({ APPLICATION_JSON, APPLICATION_OCTET_STREAM }) 116 @Operation(description = "Returns the icon for a family.") 117 @APIResponse(responseCode = "200", 118 description = "Returns a particular family icon in raw bytes.", 119 content = @Content(mediaType = APPLICATION_OCTET_STREAM)) 120 @APIResponse(responseCode = "404", 121 description = "The family or icon is not found.", 122 content = @Content(mediaType = APPLICATION_JSON, 123 schema = @Schema(type = OBJECT, implementation = ErrorPayload.class))) 124 Response familyIcon( 125 @PathParam("id") @Parameter(name = "id", description = "Family identifier.", in = PATH) String id, 126 @QueryParam("theme") @Parameter(name = "theme", 127 description = "Theme selector (light/dark). Defaults to light.") String theme); 128 129 @GET 130 @Path("icon/{id}") 131 @Produces({ APPLICATION_JSON, APPLICATION_OCTET_STREAM }) 132 @Operation(description = "Returns a particular component icon in raw bytes.") 133 @APIResponse(responseCode = "200", 134 description = "The component icon in binary form.", 135 content = @Content(mediaType = APPLICATION_OCTET_STREAM)) 136 @APIResponse(responseCode = "404", 137 description = "The family or icon is not found.", 138 content = @Content(mediaType = APPLICATION_JSON)) 139 Response icon( 140 @PathParam("id") @Parameter(name = "id", description = "Component icon identifier.", in = PATH) String id, 141 @QueryParam("theme") @Parameter(name = "theme", 142 description = "Theme selector (light/dark). Defaults to light.") String theme); 143 144 @GET 145 @Path("icon/custom/{familyId}/{iconKey}") 146 @Produces({ APPLICATION_JSON, APPLICATION_OCTET_STREAM }) 147 @Operation(description = "Returns a particular key icon in raw bytes.") 148 @APIResponse(responseCode = "200", 149 description = "The icon in binary form.", 150 content = @Content(mediaType = APPLICATION_OCTET_STREAM)) 151 @APIResponse(responseCode = "404", 152 description = "The family or icon is not found.", 153 content = @Content(mediaType = APPLICATION_JSON)) 154 Response icon( 155 @PathParam("familyId") @Parameter(name = "familyId", description = "family identifier.", 156 in = PATH) String familyId, 157 @PathParam("iconKey") @Parameter(name = "iconKey", description = "icon key.", in = PATH) String iconKey, 158 @QueryParam("theme") @Parameter(name = "theme", 159 description = "Theme selector (light/dark). Defaults to light.") String theme); 160 161 @GET 162 @Path("icon/index") 163 @Produces({ APPLICATION_JSON, IMAGE_SVG_XML }) 164 @Operation(description = "Returns list of available svg icons.") 165 @APIResponse(responseCode = "200", description = "The icon list.", 166 content = @Content(mediaType = IMAGE_SVG_XML)) 167 @APIResponse(responseCode = "404", description = "No icon found.", content = @Content(mediaType = APPLICATION_JSON)) 168 Response getIconIndex( 169 @QueryParam("theme") @Parameter(name = "theme", 170 description = "Theme selector (light/dark/all). Defaults to light.") String theme); 171 172 @POST 173 @Path("migrate/{id}/{configurationVersion}") 174 @Operation(operationId = "migrateComponent", 175 description = "Allows to migrate a component configuration without calling any component execution.") 176 @APIResponse(responseCode = "200", 177 description = "New configuration for that component (or the same if no migration was needed).", 178 content = @Content(mediaType = APPLICATION_JSON)) 179 @APIResponse(responseCode = "404", 180 description = "The component is not found.", 181 content = @Content(mediaType = APPLICATION_JSON, 182 schema = @Schema(type = OBJECT, implementation = ErrorPayload.class))) 183 Map<String, String> migrate( 184 @PathParam("id") @Parameter(name = "id", 185 description = "Component identifier.", in = PATH) String id, 186 @PathParam("configurationVersion") @Parameter(name = "configurationVersion", 187 description = "Configuration version sent, corresponding to the body content.", 188 in = PATH) int version, 189 @RequestBody(description = "Actual configuration in key/value json form.", required = true, 190 content = @Content(mediaType = APPLICATION_JSON, 191 schema = @Schema(type = OBJECT))) Map<String, String> config); 192 193 @GET 194 @Path("details") 195 @Operation(operationId = "getComponentDetail", 196 description = "Returns the set of metadata about one or multiples components identified by their 'id'.") 197 @APIResponse(responseCode = "200", 198 description = "List of details for the requested components.", 199 content = @Content(mediaType = APPLICATION_JSON)) 200 @APIResponse(responseCode = "400", 201 description = "Some identifiers were not valid.", 202 content = @Content(mediaType = APPLICATION_JSON, 203 schema = @Schema(type = OBJECT, implementation = SampleErrorForBulk.class))) 204 ComponentDetailList getDetail( 205 @QueryParam("language") @DefaultValue("en") @Parameter(name = "language", 206 description = "Response language in i18n format.", 207 in = QUERY, 208 schema = @Schema(type = STRING, defaultValue = "en")) String language, 209 @QueryParam("identifiers") @Parameter(name = "identifiers", 210 description = "The identifier id to request. " + 211 "Repeat this parameter to request more than one element.", 212 213 in = QUERY) String[] ids); 214 215 // @Unused, only for sample 216 class SampleErrorForBulk { 217 218 private ErrorPayload error1; 219 220 private ErrorPayload error2; 221 } 222}