Create resources for namespaces

This commit is contained in:
René Pfeuffer
2020-09-03 10:56:38 +02:00
parent 4d09f71d40
commit 4457cd08b8
15 changed files with 567 additions and 15 deletions

View File

@@ -0,0 +1,77 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import de.otto.edison.hal.HalRepresentation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import sonia.scm.repository.RepositoryManager;
import sonia.scm.web.VndMediaType;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
public class NamespaceCollectionResource {
private final RepositoryManager manager;
private final NamespaceCollectionToDtoMapper repositoryCollectionToDtoMapper;
@Inject
public NamespaceCollectionResource(RepositoryManager manager, NamespaceCollectionToDtoMapper repositoryCollectionToDtoMapper) {
this.manager = manager;
this.repositoryCollectionToDtoMapper = repositoryCollectionToDtoMapper;
}
/**
* Returns all namespaces.
*/
@GET
@Path("")
@Produces(VndMediaType.NAMESPACE_COLLECTION)
@Operation(summary = "List of namespaces", description = "Returns all namespaces.", tags = "Namespace")
@ApiResponse(
responseCode = "200",
description = "success",
content = @Content(
mediaType = VndMediaType.NAMESPACE_COLLECTION,
schema = @Schema(implementation = CollectionDto.class)
)
)
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(
responseCode = "500",
description = "internal server error",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
))
public HalRepresentation getAll() {
return repositoryCollectionToDtoMapper.map(manager.getAllNamespaces());
}
}

View File

@@ -0,0 +1,57 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.HalRepresentation;
import javax.inject.Inject;
import java.util.Collection;
import static de.otto.edison.hal.Embedded.embeddedBuilder;
import static de.otto.edison.hal.Links.linkingTo;
import static java.util.stream.Collectors.toList;
public class NamespaceCollectionToDtoMapper {
private final NamespaceToNamespaceDtoMapper namespaceMapper;
private final ResourceLinks links;
@Inject
public NamespaceCollectionToDtoMapper(NamespaceToNamespaceDtoMapper namespaceMapper, ResourceLinks links) {
this.namespaceMapper = namespaceMapper;
this.links = links;
}
public HalRepresentation map(Collection<String> namespaces) {
Embedded namespaceDtos = embeddedBuilder()
.with("namespaces", namespaces.stream().map(namespaceMapper::map).collect(toList()))
.build();
return new HalRepresentation(
linkingTo().self(links.namespaceCollection().self()).build(),
namespaceDtos
);
}
}

View File

@@ -0,0 +1,42 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Links;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class NamespaceDto extends HalRepresentation {
private String namespace;
public NamespaceDto(String namespace, Links links) {
super(links);
this.namespace = namespace;
}
}

View File

@@ -0,0 +1,100 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import sonia.scm.repository.RepositoryManager;
import sonia.scm.web.VndMediaType;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import static sonia.scm.ContextEntry.ContextBuilder.entity;
import static sonia.scm.NotFoundException.notFound;
public class NamespaceResource {
private final RepositoryManager manager;
private final NamespaceToNamespaceDtoMapper namespaceMapper;
@Inject
public NamespaceResource(RepositoryManager manager, NamespaceToNamespaceDtoMapper namespaceMapper) {
this.manager = manager;
this.namespaceMapper = namespaceMapper;
}
/**
* Returns a namespace.
*
* @param namespace the requested namespace
*/
@GET
@Path("")
@Produces(VndMediaType.NAMESPACE)
@Operation(summary = "Get single namespace", description = "Returns the namespace for the given name.", tags = "Namespace")
@ApiResponse(
responseCode = "200",
description = "success",
content = @Content(
mediaType = VndMediaType.NAMESPACE,
schema = @Schema(implementation = NamespaceDto.class)
)
)
@ApiResponse(
responseCode = "401",
description = "not authenticated / invalid credentials"
)
@ApiResponse(
responseCode = "404",
description = "not found, no namespace with the specified name available",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
)
)
@ApiResponse(
responseCode = "500",
description = "internal server error",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
)
)
public NamespaceDto get(@PathParam("namespace") String namespace) {
return manager.getAllNamespaces()
.stream()
.filter(n -> n.equals(namespace))
.map(namespaceMapper::map)
.findFirst()
.orElseThrow(() -> notFound(entity("Namespace", namespace)));
}
}

View File

@@ -0,0 +1,64 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.tags.Tag;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.ws.rs.Path;
/**
* RESTful Web Service Resource to manage namespaces.
*/
@OpenAPIDefinition(
tags = {
@Tag(name = "Namespace", description = "Namespace related endpoints")
}
)
@Path(NamespaceRootResource.NAMESPACE_PATH_V2)
public class NamespaceRootResource {
static final String NAMESPACE_PATH_V2 = "v2/namespaces/";
private final Provider<NamespaceCollectionResource> namespaceCollectionResource;
private final Provider<NamespaceResource> namespaceResource;
@Inject
public NamespaceRootResource(Provider<NamespaceCollectionResource> namespaceCollectionResource, Provider<NamespaceResource> namespaceResource) {
this.namespaceCollectionResource = namespaceCollectionResource;
this.namespaceResource = namespaceResource;
}
@Path("{namespace}")
public NamespaceResource getNamespaceResource() {
return namespaceResource.get();
}
@Path("")
public NamespaceCollectionResource getNamespaceCollectionResource() {
return namespaceCollectionResource.get();
}
}

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import de.otto.edison.hal.Links;
@@ -48,8 +48,8 @@ public class NamespaceStrategyResource {
static final String PATH = "v2/namespaceStrategies";
private Set<NamespaceStrategy> namespaceStrategies;
private Provider<NamespaceStrategy> namespaceStrategyProvider;
private final Set<NamespaceStrategy> namespaceStrategies;
private final Provider<NamespaceStrategy> namespaceStrategyProvider;
@Inject
public NamespaceStrategyResource(Set<NamespaceStrategy> namespaceStrategies, Provider<NamespaceStrategy> namespaceStrategyProvider) {

View File

@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import javax.inject.Inject;
import static de.otto.edison.hal.Links.linkingTo;
class NamespaceToNamespaceDtoMapper {
private final ResourceLinks links;
@Inject
NamespaceToNamespaceDtoMapper(ResourceLinks links) {
this.links = links;
}
NamespaceDto map(String namespace) {
return new NamespaceDto(namespace, linkingTo().self(links.namespace().self(namespace)).build());
}
}

View File

@@ -876,4 +876,36 @@ class ResourceLinks {
return permissionsLinkBuilder.method("getAll").parameters().href();
}
}
public NamespaceCollectionLinks namespaceCollection() {
return new NamespaceCollectionLinks(scmPathInfoStore.get());
}
static class NamespaceCollectionLinks {
private final LinkBuilder namespaceCollectionLinkBuilder;
NamespaceCollectionLinks(ScmPathInfo scmPathInfo) {
this.namespaceCollectionLinkBuilder = new LinkBuilder(scmPathInfo, NamespaceRootResource.class, NamespaceCollectionResource.class);
}
String self() {
return namespaceCollectionLinkBuilder.method("getNamespaceCollectionResource").parameters().method("getAll").parameters().href();
}
}
public NamespaceLinks namespace() {
return new NamespaceLinks(scmPathInfoStore.get());
}
static class NamespaceLinks {
private final LinkBuilder namespaceLinkBuilder;
NamespaceLinks(ScmPathInfo scmPathInfo) {
this.namespaceLinkBuilder = new LinkBuilder(scmPathInfo, NamespaceRootResource.class, NamespaceResource.class);
}
String self(String namespace) {
return namespaceLinkBuilder.method("getNamespaceResource").parameters().method("get").parameters(namespace).href();
}
}
}

View File

@@ -61,6 +61,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.function.Predicate;
import static java.util.stream.Collectors.toSet;
import static sonia.scm.AlreadyExistsException.alreadyExists;
import static sonia.scm.ContextEntry.ContextBuilder.entity;
import static sonia.scm.NotFoundException.notFound;
@@ -330,6 +331,13 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
return getAll(null, start, limit);
}
@Override
public Collection<String> getAllNamespaces() {
return getAll().stream()
.map(Repository::getNamespace)
.collect(toSet());
}
@Override
public Collection<RepositoryType> getConfiguredTypes() {
List<RepositoryType> validTypes = Lists.newArrayList();