| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.nifi.registry.web.api; |
| |
| import io.swagger.annotations.Api; |
| import io.swagger.annotations.ApiOperation; |
| import io.swagger.annotations.ApiParam; |
| import io.swagger.annotations.ApiResponse; |
| import io.swagger.annotations.ApiResponses; |
| import io.swagger.annotations.Authorization; |
| import org.apache.nifi.registry.event.EventService; |
| import org.apache.nifi.registry.extension.bundle.BundleType; |
| import org.apache.nifi.registry.extension.bundle.BundleTypeValues; |
| import org.apache.nifi.registry.extension.component.ExtensionFilterParams; |
| import org.apache.nifi.registry.extension.component.ExtensionMetadata; |
| import org.apache.nifi.registry.extension.component.ExtensionMetadataContainer; |
| import org.apache.nifi.registry.extension.component.TagCount; |
| import org.apache.nifi.registry.extension.component.manifest.ExtensionType; |
| import org.apache.nifi.registry.extension.component.manifest.ProvidedServiceAPI; |
| import org.apache.nifi.registry.security.authorization.RequestAction; |
| import org.apache.nifi.registry.service.AuthorizationService; |
| import org.apache.nifi.registry.service.RegistryService; |
| import org.apache.nifi.registry.web.link.LinkService; |
| import org.springframework.stereotype.Component; |
| |
| import javax.ws.rs.Consumes; |
| import javax.ws.rs.GET; |
| import javax.ws.rs.Path; |
| import javax.ws.rs.Produces; |
| import javax.ws.rs.QueryParam; |
| import javax.ws.rs.core.MediaType; |
| import javax.ws.rs.core.Response; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Set; |
| import java.util.SortedSet; |
| |
| @Component |
| @Path("/extensions") |
| @Api( |
| value = "extensions", |
| description = "Find and retrieve extensions. ", |
| authorizations = { @Authorization("Authorization") } |
| ) |
| public class ExtensionResource extends AuthorizableApplicationResource { |
| |
| private final RegistryService registryService; |
| private final LinkService linkService; |
| |
| public ExtensionResource(final AuthorizationService authorizationService, |
| final EventService eventService, |
| final RegistryService registryService, |
| final LinkService linkService) { |
| super(authorizationService, eventService); |
| this.registryService = registryService; |
| this.linkService = linkService; |
| } |
| |
| @GET |
| @Consumes(MediaType.WILDCARD) |
| @Produces(MediaType.APPLICATION_JSON) |
| @ApiOperation( |
| value = "Get all extensions", |
| notes = "Gets the metadata for all extensions that match the filter params and are part of bundles located in buckets the " + |
| "current user is authorized for. If the user is not authorized to any buckets, an empty result set will be returned." + |
| NON_GUARANTEED_ENDPOINT, |
| response = ExtensionMetadataContainer.class |
| ) |
| @ApiResponses({ |
| @ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), |
| @ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), |
| @ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), |
| @ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), |
| @ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409) }) |
| public Response getExtensions( |
| @QueryParam("bundleType") |
| @ApiParam(value = "The type of bundles to return", allowableValues = BundleTypeValues.ALL_VALUES) |
| final BundleType bundleType, |
| @QueryParam("extensionType") |
| @ApiParam(value = "The type of extensions to return") |
| final ExtensionType extensionType, |
| @QueryParam("tag") |
| @ApiParam(value = "The tags to filter on, will be used in an OR statement") |
| final Set<String> tags |
| ) { |
| |
| final Set<String> authorizedBucketIds = getAuthorizedBucketIds(RequestAction.READ); |
| if (authorizedBucketIds == null || authorizedBucketIds.isEmpty()) { |
| // not authorized for any bucket, return empty list of items |
| return Response.status(Response.Status.OK).entity(new ArrayList<>()).build(); |
| } |
| |
| final ExtensionFilterParams filterParams = new ExtensionFilterParams.Builder() |
| .bundleType(bundleType) |
| .extensionType(extensionType) |
| .addTags(tags == null ? Collections.emptyList() : tags) |
| .build(); |
| |
| final SortedSet<ExtensionMetadata> extensionMetadata = registryService.getExtensionMetadata(authorizedBucketIds, filterParams); |
| linkService.populateLinks(extensionMetadata); |
| |
| final ExtensionMetadataContainer container = new ExtensionMetadataContainer(); |
| container.setExtensions(extensionMetadata); |
| container.setNumResults(extensionMetadata.size()); |
| container.setFilterParams(filterParams); |
| |
| return Response.status(Response.Status.OK).entity(container).build(); |
| } |
| |
| @GET |
| @Path("provided-service-api") |
| @Consumes(MediaType.WILDCARD) |
| @Produces(MediaType.APPLICATION_JSON) |
| @ApiOperation( |
| value = "Get extensions providing service API", |
| notes = "Gets the metadata for extensions that provide the specified API and are part of bundles located in buckets the " + |
| "current user is authorized for. If the user is not authorized to any buckets, an empty result set will be returned." + |
| NON_GUARANTEED_ENDPOINT, |
| response = ExtensionMetadataContainer.class |
| ) |
| @ApiResponses({ |
| @ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), |
| @ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), |
| @ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), |
| @ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), |
| @ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409) }) |
| public Response getExtensionsProvidingServiceAPI( |
| @QueryParam("className") |
| @ApiParam(value = "The name of the service API class", required = true) |
| final String className, |
| @QueryParam("groupId") |
| @ApiParam(value = "The groupId of the bundle containing the service API class", required = true) |
| final String groupId, |
| @QueryParam("artifactId") |
| @ApiParam(value = "The artifactId of the bundle containing the service API class", required = true) |
| final String artifactId, |
| @QueryParam("version") |
| @ApiParam(value = "The version of the bundle containing the service API class", required = true) |
| final String version |
| ) { |
| |
| final Set<String> authorizedBucketIds = getAuthorizedBucketIds(RequestAction.READ); |
| if (authorizedBucketIds == null || authorizedBucketIds.isEmpty()) { |
| // not authorized for any bucket, return empty list of items |
| return Response.status(Response.Status.OK).entity(new ArrayList<>()).build(); |
| } |
| |
| final ProvidedServiceAPI serviceAPI = new ProvidedServiceAPI(); |
| serviceAPI.setClassName(className); |
| serviceAPI.setGroupId(groupId); |
| serviceAPI.setArtifactId(artifactId); |
| serviceAPI.setVersion(version); |
| |
| final SortedSet<ExtensionMetadata> extensionMetadata = registryService.getExtensionMetadata(authorizedBucketIds, serviceAPI); |
| linkService.populateLinks(extensionMetadata); |
| |
| final ExtensionMetadataContainer container = new ExtensionMetadataContainer(); |
| container.setExtensions(extensionMetadata); |
| container.setNumResults(extensionMetadata.size()); |
| |
| return Response.status(Response.Status.OK).entity(container).build(); |
| } |
| |
| @GET |
| @Path("/tags") |
| @Consumes(MediaType.WILDCARD) |
| @Produces(MediaType.APPLICATION_JSON) |
| @ApiOperation( |
| value = "Get extension tags", |
| notes = "Gets all the extension tags known to this NiFi Registry instance, along with the " + |
| "number of extensions that have the given tag." + NON_GUARANTEED_ENDPOINT, |
| response = TagCount.class, |
| responseContainer = "List" |
| ) |
| @ApiResponses({ |
| @ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), |
| @ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), |
| @ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), |
| @ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), |
| @ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409) }) |
| public Response getTags() { |
| final SortedSet<TagCount> tags = registryService.getExtensionTags(); |
| return Response.status(Response.Status.OK).entity(tags).build(); |
| } |
| |
| } |