Integrate import repository function into ui

This commit is contained in:
Eduard Heimbuch
2020-11-25 11:23:43 +01:00
parent ff2b4d8acd
commit 10ed51733c
7 changed files with 251 additions and 205 deletions

View File

@@ -39,6 +39,12 @@ export type RepositoryCreation = Repository & {
contextEntries: { [key: string]: any }; contextEntries: { [key: string]: any };
}; };
export type RepositoryImport = Repository & {
importUrl?: string;
username?: string;
password?: string;
};
export type Namespace = { export type Namespace = {
namespace: string; namespace: string;
_links: Links; _links: Links;

View File

@@ -37,7 +37,7 @@ import { binder, ExtensionPoint } from "@scm-manager/ui-extensions";
import CreateUser from "../users/containers/CreateUser"; import CreateUser from "../users/containers/CreateUser";
import SingleUser from "../users/containers/SingleUser"; import SingleUser from "../users/containers/SingleUser";
import RepositoryRoot from "../repos/containers/RepositoryRoot"; import RepositoryRoot from "../repos/containers/RepositoryRoot";
import Create from "../repos/containers/Create"; import AddRepository from "../repos/containers/AddRepository";
import Groups from "../groups/containers/Groups"; import Groups from "../groups/containers/Groups";
import SingleGroup from "../groups/containers/SingleGroup"; import SingleGroup from "../groups/containers/SingleGroup";
@@ -77,8 +77,8 @@ class Main extends React.Component<Props> {
<Route path="/logout" component={Logout} /> <Route path="/logout" component={Logout} />
<Redirect exact strict from="/repos" to="/repos/" /> <Redirect exact strict from="/repos" to="/repos/" />
<ProtectedRoute exact path="/repos/" component={Overview} authenticated={authenticated} /> <ProtectedRoute exact path="/repos/" component={Overview} authenticated={authenticated} />
<ProtectedRoute exact path="/repos/create" component={Create} authenticated={authenticated} /> <ProtectedRoute exact path="/repos/create" component={AddRepository} authenticated={authenticated} />
<ProtectedRoute exact path="/repos/import" component={Create} authenticated={authenticated} /> <ProtectedRoute exact path="/repos/import" component={AddRepository} authenticated={authenticated} />
<ProtectedRoute exact path="/repos/:namespace" component={Overview} authenticated={authenticated} /> <ProtectedRoute exact path="/repos/:namespace" component={Overview} authenticated={authenticated} />
<ProtectedRoute exact path="/repos/:namespace/:page" component={Overview} authenticated={authenticated} /> <ProtectedRoute exact path="/repos/:namespace/:page" component={Overview} authenticated={authenticated} />
<ProtectedRoute path="/repo/:namespace/:name" component={RepositoryRoot} authenticated={authenticated} /> <ProtectedRoute path="/repo/:namespace/:name" component={RepositoryRoot} authenticated={authenticated} />

View File

@@ -25,7 +25,7 @@ import React, { FC, useEffect, useState } from "react";
import styled from "styled-components"; import styled from "styled-components";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { ExtensionPoint } from "@scm-manager/ui-extensions"; import { ExtensionPoint } from "@scm-manager/ui-extensions";
import { Repository, RepositoryType } from "@scm-manager/ui-types"; import { Repository, RepositoryType, RepositoryImport } from "@scm-manager/ui-types";
import { Checkbox, InputField, Level, Select, SubmitButton, Textarea } from "@scm-manager/ui-components"; import { Checkbox, InputField, Level, Select, SubmitButton, Textarea } from "@scm-manager/ui-components";
import * as validator from "./repositoryValidation"; import * as validator from "./repositoryValidation";
import { CUSTOM_NAMESPACE_STRATEGY } from "../../modules/repos"; import { CUSTOM_NAMESPACE_STRATEGY } from "../../modules/repos";
@@ -56,13 +56,13 @@ const Columns = styled.div`
type Props = { type Props = {
createRepository?: (repo: RepositoryCreation, shouldInit: boolean) => void; createRepository?: (repo: RepositoryCreation, shouldInit: boolean) => void;
modifyRepository?: (repo: RepositoryCreation) => void; importRepository?: (repo: RepositoryImport) => void;
importRepository?: (repo: RepositoryCreation) => void; modifyRepository?: (repo: Repository) => void;
repository?: Repository; repository?: Repository;
repositoryTypes?: RepositoryType[]; repositoryTypes?: RepositoryType[];
namespaceStrategy?: string; namespaceStrategy?: string;
loading?: boolean; loading?: boolean;
indexResources: any; indexResources?: any;
}; };
type RepositoryCreation = Repository & { type RepositoryCreation = Repository & {
@@ -118,19 +118,14 @@ const RepositoryForm: FC<Props> = ({
const submit = (event: React.FormEvent<HTMLFormElement>) => { const submit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault(); event.preventDefault();
const submitForm = evaluateSubmit(); if (isValid()) {
if (isValid() && submitForm) { if (importRepository && isImportPage()) {
submitForm(repo, initRepository); importRepository({ ...repo, url: importUrl, username, password });
} } else if (createRepository && isCreatePage()) {
}; createRepository(repo, initRepository);
} else if (modifyRepository) {
const evaluateSubmit = () => { modifyRepository(repo);
if (isImportPage()) { }
return importRepository;
} else if (isCreatePage()) {
return createRepository;
} else {
return modifyRepository;
} }
}; };
@@ -167,13 +162,8 @@ const RepositoryForm: FC<Props> = ({
return ""; return "";
}; };
const isImportPage = () => { const isImportPage = () => resolveLocation() === "import";
return resolveLocation() === "import"; const isCreatePage = () => resolveLocation() === "create";
};
const isCreatePage = () => {
return resolveLocation() === "create";
};
const createSelectOptions = (repositoryTypes?: RepositoryType[]) => { const createSelectOptions = (repositoryTypes?: RepositoryType[]) => {
if (repositoryTypes) { if (repositoryTypes) {
@@ -311,7 +301,7 @@ const RepositoryForm: FC<Props> = ({
if (!repo.name) { if (!repo.name) {
const match = url.match(/([^\/]+)\.git/i); const match = url.match(/([^\/]+)\.git/i);
if (match && match[1]) { if (match && match[1]) {
setRepo({ ...repo, name: match[1] }); handleNameChange(match[1]);
} }
} }
setImportUrl(url); setImportUrl(url);
@@ -319,9 +309,8 @@ const RepositoryForm: FC<Props> = ({
const disabled = !isModifiable() && isEditMode(); const disabled = !isModifiable() && isEditMode();
const getSubmitButtonTranslationKey = () => { const getSubmitButtonTranslationKey = () =>
return isImportPage() ? "repositoryForm.submitImport" : "repositoryForm.submitCreate"; isImportPage() ? "repositoryForm.submitImport" : "repositoryForm.submitCreate";
};
const submitButton = disabled ? null : ( const submitButton = disabled ? null : (
<Level <Level

View File

@@ -25,7 +25,13 @@ import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { WithTranslation, withTranslation } from "react-i18next"; import { WithTranslation, withTranslation } from "react-i18next";
import { History } from "history"; import { History } from "history";
import { NamespaceStrategies, Repository, RepositoryCreation, RepositoryType } from "@scm-manager/ui-types"; import {
NamespaceStrategies,
Repository,
RepositoryCreation,
RepositoryImport,
RepositoryType
} from "@scm-manager/ui-types";
import { Page } from "@scm-manager/ui-components"; import { Page } from "@scm-manager/ui-components";
import { import {
fetchRepositoryTypesIfNeeded, fetchRepositoryTypesIfNeeded,
@@ -34,7 +40,13 @@ import {
isFetchRepositoryTypesPending isFetchRepositoryTypesPending
} from "../modules/repositoryTypes"; } from "../modules/repositoryTypes";
import RepositoryForm from "../components/form"; import RepositoryForm from "../components/form";
import { createRepo, createRepoReset, getCreateRepoFailure, isCreateRepoPending } from "../modules/repos"; import {
createRepo,
createRepoReset,
getCreateRepoFailure,
importRepoFromUrl,
isCreateRepoPending
} from "../modules/repos";
import { getRepositoriesLink } from "../../modules/indexResource"; import { getRepositoriesLink } from "../../modules/indexResource";
import { import {
fetchNamespaceStrategiesIfNeeded, fetchNamespaceStrategiesIfNeeded,
@@ -61,13 +73,14 @@ type Props = WithTranslation & {
initRepository: boolean, initRepository: boolean,
callback: (repo: Repository) => void callback: (repo: Repository) => void
) => void; ) => void;
importRepoFromUrl: (link: string, repository: RepositoryImport, callback: (repo: Repository) => void) => void;
resetForm: () => void; resetForm: () => void;
// context props // context props
history: History; history: History;
}; };
class Create extends React.Component<Props> { class AddRepository extends React.Component<Props> {
componentDidMount() { componentDidMount() {
this.props.resetForm(); this.props.resetForm();
this.props.fetchRepositoryTypesIfNeeded(); this.props.fetchRepositoryTypesIfNeeded();
@@ -87,18 +100,15 @@ class Create extends React.Component<Props> {
repositoryTypes, repositoryTypes,
namespaceStrategies, namespaceStrategies,
createRepo, createRepo,
importRepoFromUrl,
error, error,
indexResources indexResources,
repoLink,
t
} = this.props; } = this.props;
const { t, repoLink } = this.props;
return ( return (
<Page <Page title={t("create.title")} loading={pageLoading} error={error} showContentOnError={true}>
title={t("create.title")}
loading={pageLoading}
error={error}
showContentOnError={true}
>
<RepositoryForm <RepositoryForm
repositoryTypes={repositoryTypes} repositoryTypes={repositoryTypes}
loading={createLoading} loading={createLoading}
@@ -106,6 +116,9 @@ class Create extends React.Component<Props> {
createRepository={(repo, initRepository) => { createRepository={(repo, initRepository) => {
createRepo(repoLink, repo, initRepository, (repo: Repository) => this.repoCreated(repo)); createRepo(repoLink, repo, initRepository, (repo: Repository) => this.repoCreated(repo));
}} }}
importRepository={repo => {
importRepoFromUrl(repoLink, repo, (repo: Repository) => this.repoCreated(repo));
}}
indexResources={indexResources} indexResources={indexResources}
/> />
</Page> </Page>
@@ -145,10 +158,13 @@ const mapDispatchToProps = (dispatch: any) => {
createRepo: (link: string, repository: RepositoryCreation, initRepository: boolean, callback: () => void) => { createRepo: (link: string, repository: RepositoryCreation, initRepository: boolean, callback: () => void) => {
dispatch(createRepo(link, repository, initRepository, callback)); dispatch(createRepo(link, repository, initRepository, callback));
}, },
importRepoFromUrl: (link: string, repository: RepositoryImport, callback: () => void) => {
dispatch(importRepoFromUrl(link, repository, callback));
},
resetForm: () => { resetForm: () => {
dispatch(createRepoReset()); dispatch(createRepoReset());
} }
}; };
}; };
export default connect(mapStateToProps, mapDispatchToProps)(withTranslation("repos")(Create)); export default connect(mapStateToProps, mapDispatchToProps)(withTranslation("repos")(AddRepository));

View File

@@ -75,7 +75,7 @@ class EditRepo extends React.Component<Props> {
<RepositoryForm <RepositoryForm
repository={this.props.repository} repository={this.props.repository}
loading={loading} loading={loading}
createRepository={repo => { modifyRepository={repo => {
this.props.modifyRepo(repo, this.repoModified); this.props.modifyRepo(repo, this.repoModified);
}} }}
/> />

View File

@@ -25,11 +25,14 @@
import { apiClient } from "@scm-manager/ui-components"; import { apiClient } from "@scm-manager/ui-components";
import * as types from "../../modules/types"; import * as types from "../../modules/types";
import { import {
Action, Namespace, Action,
Namespace,
NamespaceCollection, NamespaceCollection,
Repository, Repository,
RepositoryCollection, RepositoryCollection,
RepositoryCreation RepositoryCreation,
RepositoryImport,
Link
} from "@scm-manager/ui-types"; } from "@scm-manager/ui-types";
import { isPending } from "../../modules/pending"; import { isPending } from "../../modules/pending";
import { getFailure } from "../../modules/failure"; import { getFailure } from "../../modules/failure";
@@ -55,6 +58,12 @@ export const CREATE_REPO_SUCCESS = `${CREATE_REPO}_${types.SUCCESS_SUFFIX}`;
export const CREATE_REPO_FAILURE = `${CREATE_REPO}_${types.FAILURE_SUFFIX}`; export const CREATE_REPO_FAILURE = `${CREATE_REPO}_${types.FAILURE_SUFFIX}`;
export const CREATE_REPO_RESET = `${CREATE_REPO}_${types.RESET_SUFFIX}`; export const CREATE_REPO_RESET = `${CREATE_REPO}_${types.RESET_SUFFIX}`;
export const IMPORT_REPO = "scm/repos/IMPORT_REPO";
export const IMPORT_REPO_PENDING = `${IMPORT_REPO}_${types.PENDING_SUFFIX}`;
export const IMPORT_REPO_SUCCESS = `${IMPORT_REPO}_${types.SUCCESS_SUFFIX}`;
export const IMPORT_REPO_FAILURE = `${IMPORT_REPO}_${types.FAILURE_SUFFIX}`;
export const IMPORT_REPO_RESET = `${IMPORT_REPO}_${types.RESET_SUFFIX}`;
export const MODIFY_REPO = "scm/repos/MODIFY_REPO"; export const MODIFY_REPO = "scm/repos/MODIFY_REPO";
export const MODIFY_REPO_PENDING = `${MODIFY_REPO}_${types.PENDING_SUFFIX}`; export const MODIFY_REPO_PENDING = `${MODIFY_REPO}_${types.PENDING_SUFFIX}`;
export const MODIFY_REPO_SUCCESS = `${MODIFY_REPO}_${types.SUCCESS_SUFFIX}`; export const MODIFY_REPO_SUCCESS = `${MODIFY_REPO}_${types.SUCCESS_SUFFIX}`;
@@ -178,7 +187,7 @@ export function fetchNamespacesFailure(err: Error): Action {
// fetch repo // fetch repo
export function fetchRepoByLink(repo: Repository) { export function fetchRepoByLink(repo: Repository) {
return fetchRepo(repo._links.self.href, repo.namespace, repo.name); return fetchRepo((repo._links.self as Link).href, repo.namespace, repo.name);
} }
export function fetchRepoByName(link: string, namespace: string, name: string) { export function fetchRepoByName(link: string, namespace: string, name: string) {
@@ -232,6 +241,50 @@ export function fetchRepoFailure(namespace: string, name: string, error: Error):
}; };
} }
// import repo
export function importRepoFromUrl(link: string, repository: RepositoryImport, callback?: (repo: Repository) => void) {
const importLink = link + `import/${repository.type}/url`;
return function(dispatch: any) {
dispatch(importRepoPending());
return apiClient
.post(importLink, repository, CONTENT_TYPE)
.then(response => {
const location = response.headers.get("Location");
dispatch(importRepoSuccess());
return apiClient.get(location);
})
.then(response => response.json())
.then(response => {
if (callback) {
callback(response);
}
})
.catch(err => {
dispatch(importRepoFailure(err));
});
};
}
export function importRepoPending(): Action {
return {
type: CREATE_REPO_PENDING
};
}
export function importRepoSuccess(): Action {
return {
type: CREATE_REPO_SUCCESS
};
}
export function importRepoFailure(err: Error): Action {
return {
type: CREATE_REPO_FAILURE,
payload: err
};
}
// create repo // create repo
export function createRepo( export function createRepo(
@@ -294,7 +347,7 @@ export function modifyRepo(repository: Repository, callback?: () => void) {
dispatch(modifyRepoPending(repository)); dispatch(modifyRepoPending(repository));
return apiClient return apiClient
.put(repository._links.update.href, repository, CONTENT_TYPE) .put((repository._links.update as Link).href, repository, CONTENT_TYPE)
.then(() => { .then(() => {
dispatch(modifyRepoSuccess(repository)); dispatch(modifyRepoSuccess(repository));
if (callback) { if (callback) {
@@ -353,7 +406,7 @@ export function deleteRepo(repository: Repository, callback?: () => void) {
return function(dispatch: any) { return function(dispatch: any) {
dispatch(deleteRepoPending(repository)); dispatch(deleteRepoPending(repository));
return apiClient return apiClient
.delete(repository._links.delete.href) .delete((repository._links.delete as Link).href)
.then(() => { .then(() => {
dispatch(deleteRepoSuccess(repository)); dispatch(deleteRepoSuccess(repository));
if (callback) { if (callback) {

View File

@@ -25,17 +25,18 @@
package sonia.scm.api.v2.resources; package sonia.scm.api.v2.resources;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.io.Files;
import com.google.inject.Inject; import com.google.inject.Inject;
import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.Links;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.ToString; import lombok.Getter;
import lombok.Value; import lombok.NoArgsConstructor;
import lombok.Setter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import sonia.scm.FeatureNotSupportedException;
import sonia.scm.NotFoundException; import sonia.scm.NotFoundException;
import sonia.scm.Type; import sonia.scm.Type;
import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.InternalRepositoryException;
@@ -47,7 +48,6 @@ import sonia.scm.repository.RepositoryType;
import sonia.scm.repository.api.Command; import sonia.scm.repository.api.Command;
import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryService;
import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.repository.api.RepositoryServiceFactory;
import sonia.scm.util.IOUtil;
import sonia.scm.web.VndMediaType; import sonia.scm.web.VndMediaType;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
@@ -56,19 +56,10 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException; import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context; import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.URI; import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set; import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
@@ -80,12 +71,14 @@ public class RepositoryImportResource {
private final RepositoryManager manager; private final RepositoryManager manager;
private final RepositoryServiceFactory serviceFactory; private final RepositoryServiceFactory serviceFactory;
private final ResourceLinks resourceLinks;
@Inject @Inject
public RepositoryImportResource(RepositoryManager manager, public RepositoryImportResource(RepositoryManager manager,
RepositoryServiceFactory serviceFactory) { RepositoryServiceFactory serviceFactory, ResourceLinks resourceLinks) {
this.manager = manager; this.manager = manager;
this.serviceFactory = serviceFactory; this.serviceFactory = serviceFactory;
this.resourceLinks = resourceLinks;
} }
// /** // /**
@@ -171,7 +164,7 @@ public class RepositoryImportResource {
*/ */
@POST @POST
@Path("{type}/url") @Path("{type}/url")
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Consumes(VndMediaType.REPOSITORY)
@Operation(summary = "Import repository from url", description = "Imports the repository for the given url.", tags = "Repository") @Operation(summary = "Import repository from url", description = "Imports the repository for the given url.", tags = "Repository")
@ApiResponse( @ApiResponse(
responseCode = "201", responseCode = "201",
@@ -198,7 +191,7 @@ public class RepositoryImportResource {
) )
) )
public Response importFromUrl(@Context UriInfo uriInfo, public Response importFromUrl(@Context UriInfo uriInfo,
@PathParam("type") String type, UrlImportRequest request) { @PathParam("type") String type, RepositoryImportDto request) {
RepositoryPermissions.create().check(); RepositoryPermissions.create().check();
checkNotNull(request, "request is required"); checkNotNull(request, "request is required");
checkArgument(!Strings.isNullOrEmpty(request.getName()), checkArgument(!Strings.isNullOrEmpty(request.getName()),
@@ -220,17 +213,7 @@ public class RepositoryImportResource {
handleImportFailure(ex, repository); handleImportFailure(ex, repository);
} }
return Response.created(createRepositoryLocation(uriInfo, repository)).build(); return Response.created(URI.create(resourceLinks.repository().self(repository.getNamespace(), repository.getName()))).build();
}
private URI createRepositoryLocation(UriInfo uriInfo, Repository repository) {
return URI.create(
String.format(
"%s/repos/%s",
uriInfo.getBaseUri().toString().replace("/api/", "/"),
repository.getNamespaceAndName()
)
);
} }
// /** // /**
@@ -408,81 +391,81 @@ public class RepositoryImportResource {
return repository; return repository;
} }
/** // /**
* Start bundle import. // * Start bundle import.
* // *
* @param type repository type // * @param type repository type
* @param name name of the repository // * @param name name of the repository
* @param inputStream bundle stream // * @param inputStream bundle stream
* @param compressed true if the bundle is gzip compressed // * @param compressed true if the bundle is gzip compressed
* @return imported repository // * @return imported repository
*/ // */
private Repository doImportFromBundle(String type, String namespace, String name, // private Repository doImportFromBundle(String type, String namespace, String name,
InputStream inputStream, boolean compressed) { // InputStream inputStream, boolean compressed) {
RepositoryPermissions.create().check(); // RepositoryPermissions.create().check();
//
checkArgument(!Strings.isNullOrEmpty(name), // checkArgument(!Strings.isNullOrEmpty(name),
"request does not contain name of the repository"); // "request does not contain name of the repository");
checkNotNull(inputStream, "bundle inputStream is required"); // checkNotNull(inputStream, "bundle inputStream is required");
//
Repository repository; // Repository repository;
//
try { // try {
Type t = type(type); // Type t = type(type);
checkSupport(t, Command.UNBUNDLE, "bundle"); // checkSupport(t, Command.UNBUNDLE, "bundle");
repository = create(namespace, name, type); // repository = create(namespace, name, type);
importFromBundle(repository, inputStream, compressed); // importFromBundle(repository, inputStream, compressed);
} catch (IOException ex) { // } catch (IOException ex) {
logger.warn("could not create temporary file", ex); // logger.warn("could not create temporary file", ex);
//
throw new WebApplicationException(ex); // throw new WebApplicationException(ex);
} // }
//
return repository; // return repository;
} // }
//
private void importFromBundle(Repository repository, InputStream inputStream, boolean compressed) throws IOException { // private void importFromBundle(Repository repository, InputStream inputStream, boolean compressed) throws IOException {
File file = File.createTempFile("scm-import-", ".bundle"); // File file = File.createTempFile("scm-import-", ".bundle");
//
try (RepositoryService service = serviceFactory.create(repository)) { // try (RepositoryService service = serviceFactory.create(repository)) {
long length = Files.asByteSink(file).writeFrom(inputStream); // long length = Files.asByteSink(file).writeFrom(inputStream);
//
logger.info("copied {} bytes to temp, start bundle import", length); // logger.info("copied {} bytes to temp, start bundle import", length);
service.getUnbundleCommand().setCompressed(compressed).unbundle(file); // service.getUnbundleCommand().setCompressed(compressed).unbundle(file);
} catch (InternalRepositoryException ex) { // } catch (InternalRepositoryException ex) {
handleImportFailure(ex, repository); // handleImportFailure(ex, repository);
} finally { // } finally {
IOUtil.delete(file); // IOUtil.delete(file);
} // }
} // }
//
private List<Type> findImportableTypes() { // private List<Type> findImportableTypes() {
List<Type> types = new ArrayList<>(); // List<Type> types = new ArrayList<>();
Collection<Type> handlerTypes = manager.getTypes(); // Collection<Type> handlerTypes = manager.getTypes();
//
for (Type t : handlerTypes) { // for (Type t : handlerTypes) {
RepositoryHandler handler = manager.getHandler(t.getName()); // RepositoryHandler handler = manager.getHandler(t.getName());
//
if (handler != null) { // if (handler != null) {
try { // try {
if (handler.getImportHandler() != null) { // if (handler.getImportHandler() != null) {
types.add(t); // types.add(t);
} // }
} catch (FeatureNotSupportedException ex) { // } catch (FeatureNotSupportedException ex) {
if (logger.isTraceEnabled()) { // if (logger.isTraceEnabled()) {
logger.trace("import handler is not supported", ex); // logger.trace("import handler is not supported", ex);
} else if (logger.isInfoEnabled()) { // } else if (logger.isInfoEnabled()) {
logger.info("{} handler does not support import of repositories", // logger.info("{} handler does not support import of repositories",
t.getName()); // t.getName());
} // }
} // }
} else if (logger.isWarnEnabled()) { // } else if (logger.isWarnEnabled()) {
logger.warn("could not find handler for type {}", t.getName()); // logger.warn("could not find handler for type {}", t.getName());
} // }
} // }
//
return types; // return types;
} // }
/** /**
* Handle creation failures. * Handle creation failures.
@@ -518,49 +501,49 @@ public class RepositoryImportResource {
Response.Status.INTERNAL_SERVER_ERROR); Response.Status.INTERNAL_SERVER_ERROR);
} }
/** // /**
* Import repositories from a specific type. // * Import repositories from a specific type.
* // *
* @param repositories repository list // * @param repositories repository list
* @param type type of repository // * @param type type of repository
*/ // */
private void importFromDirectory(List<Repository> repositories, String type) { // private void importFromDirectory(List<Repository> repositories, String type) {
RepositoryHandler handler = manager.getHandler(type); // RepositoryHandler handler = manager.getHandler(type);
//
if (handler != null) { // if (handler != null) {
logger.info("start directory import for repository type {}", type); // logger.info("start directory import for repository type {}", type);
//
try { // try {
List<String> repositoryNames = // List<String> repositoryNames =
handler.getImportHandler().importRepositories(manager); // handler.getImportHandler().importRepositories(manager);
//
if (repositoryNames != null) { // if (repositoryNames != null) {
for (String repositoryName : repositoryNames) { // for (String repositoryName : repositoryNames) {
// TODO #8783 // // TODO #8783
/*Repository repository = null; //manager.get(type, repositoryName); // /*Repository repository = null; //manager.get(type, repositoryName);
//
if (repository != null) // if (repository != null)
{ // {
repositories.add(repository); // repositories.add(repository);
} // }
else if (logger.isWarnEnabled()) // else if (logger.isWarnEnabled())
{ // {
logger.warn("could not find imported repository {}", // logger.warn("could not find imported repository {}",
repositoryName); // repositoryName);
}*/ // }*/
} // }
} // }
} catch (FeatureNotSupportedException ex) { // } catch (FeatureNotSupportedException ex) {
throw new WebApplicationException(ex, Response.Status.BAD_REQUEST); // throw new WebApplicationException(ex, Response.Status.BAD_REQUEST);
} catch (IOException ex) { // } catch (IOException ex) {
throw new WebApplicationException(ex); // throw new WebApplicationException(ex);
} catch (InternalRepositoryException ex) { // } catch (InternalRepositoryException ex) {
throw new WebApplicationException(ex); // throw new WebApplicationException(ex);
} // }
} else { // } else {
throw new WebApplicationException(Response.Status.BAD_REQUEST); // throw new WebApplicationException(Response.Status.BAD_REQUEST);
} // }
} // }
private Type type(String type) { private Type type(String type) {
RepositoryHandler handler = manager.getHandler(type); RepositoryHandler handler = manager.getHandler(type);
@@ -574,18 +557,17 @@ public class RepositoryImportResource {
return handler.getType(); return handler.getType();
} }
/** @Getter
* Request for importing external repositories which are accessible via url. @Setter
*/ @NoArgsConstructor
@XmlRootElement(name = "import") @SuppressWarnings("java:S2160")
@XmlAccessorType(XmlAccessType.FIELD) public static class RepositoryImportDto extends RepositoryDto {
@Value
@ToString
public static class UrlImportRequest {
private String namespace;
private String name;
private String url; private String url;
private String username; private String username;
private String password; private String password;
RepositoryImportDto(Links links, Embedded embedded) {
super(links, embedded);
}
} }
} }