From 84bcc48e6b6f96c62c6826807794cd747afa41f6 Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Sun, 22 Dec 2013 12:25:23 +0000 Subject: [PATCH] [MRM-1750] Add remote repository health check Add rest api git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1552981 13f79535-47bb-0310-9956-ffa450edef68 --- .../indexing/DownloadRemoteIndexTask.java | 9 +- .../services/RemoteRepositoriesService.java | 53 +++++---- .../archiva-rest-services/pom.xml | 6 + .../DefaultRemoteRepositoriesService.java | 110 +++++++++++++++++- 4 files changed, 145 insertions(+), 33 deletions(-) diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-indexing/src/main/java/org/apache/archiva/scheduler/indexing/DownloadRemoteIndexTask.java b/archiva-modules/archiva-scheduler/archiva-scheduler-indexing/src/main/java/org/apache/archiva/scheduler/indexing/DownloadRemoteIndexTask.java index c87617880..b8db00ae8 100644 --- a/archiva-modules/archiva-scheduler/archiva-scheduler-indexing/src/main/java/org/apache/archiva/scheduler/indexing/DownloadRemoteIndexTask.java +++ b/archiva-modules/archiva-scheduler/archiva-scheduler-indexing/src/main/java/org/apache/archiva/scheduler/indexing/DownloadRemoteIndexTask.java @@ -135,19 +135,18 @@ public class DownloadRemoteIndexTask final StreamWagon wagon = (StreamWagon) wagonFactory.getWagon( new WagonFactoryRequest( wagonProtocol, this.remoteRepository.getExtraHeaders() ).networkProxy( this.networkProxy ) ); - int timeoutInMilliseconds = remoteRepository.getTimeout() * 1000; // FIXME olamy having 2 config values - wagon.setReadTimeout( timeoutInMilliseconds ); - wagon.setTimeout( timeoutInMilliseconds ); + wagon.setReadTimeout( remoteRepository.getRemoteDownloadTimeout() * 1000 ); + wagon.setTimeout( remoteRepository.getTimeout() * 1000 ); if ( wagon instanceof AbstractHttpClientWagon ) { HttpConfiguration httpConfiguration = new HttpConfiguration(); HttpMethodConfiguration httpMethodConfiguration = new HttpMethodConfiguration(); httpMethodConfiguration.setUsePreemptive( true ); - httpMethodConfiguration.setReadTimeout( timeoutInMilliseconds ); + httpMethodConfiguration.setReadTimeout( remoteRepository.getRemoteDownloadTimeout() * 1000 ); httpConfiguration.setGet( httpMethodConfiguration ); - ( (AbstractHttpClientWagon) wagon ).setHttpConfiguration( httpConfiguration ); + AbstractHttpClientWagon.class.cast( wagon ).setHttpConfiguration( httpConfiguration ); } wagon.addTransferListener( new DownloadListener() ); diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/RemoteRepositoriesService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/RemoteRepositoriesService.java index fc861402c..19cbf5d69 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/RemoteRepositoriesService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/RemoteRepositoriesService.java @@ -36,47 +36,52 @@ import java.util.List; * @author Olivier Lamy * @since 1.4-M1 */ -@Path( "/remoteRepositoriesService/" ) +@Path("/remoteRepositoriesService/") public interface RemoteRepositoriesService { - @Path( "getRemoteRepositories" ) + @Path("getRemoteRepositories") @GET - @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) - @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION ) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION) List getRemoteRepositories() throws ArchivaRestServiceException; - @Path( "getRemoteRepository/{repositoryId}" ) + @Path("getRemoteRepository/{repositoryId}") @GET - @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) - @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION ) - RemoteRepository getRemoteRepository( @PathParam( "repositoryId" ) String repositoryId ) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION) + RemoteRepository getRemoteRepository( @PathParam("repositoryId") String repositoryId ) throws ArchivaRestServiceException; - @Path( "deleteRemoteRepository/{repositoryId}" ) + @Path("deleteRemoteRepository/{repositoryId}") @GET - @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } ) - @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION ) - Boolean deleteRemoteRepository( @PathParam( "repositoryId" ) String repositoryId ) - throws Exception; + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN }) + @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION) + Boolean deleteRemoteRepository( @PathParam("repositoryId") String repositoryId ) + throws ArchivaRestServiceException; - @Path( "addRemoteRepository" ) + @Path("addRemoteRepository") @POST - @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) - @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } ) - @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION ) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN }) + @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION) Boolean addRemoteRepository( RemoteRepository remoteRepository ) - throws Exception; + throws ArchivaRestServiceException; - @Path( "updateRemoteRepository" ) + @Path("updateRemoteRepository") @POST - @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) - @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } ) - @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION ) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN }) + @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION) Boolean updateRemoteRepository( RemoteRepository remoteRepository ) - throws Exception; - + throws ArchivaRestServiceException; + @Path("checkRemoteConnectivity/{repositoryId}") + @GET + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN }) + @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION) + Boolean checkRemoteConnectivity( @PathParam( "repositoryId" ) String repositoryId ) + throws ArchivaRestServiceException; } diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml index 345665151..e58c40a36 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml @@ -158,6 +158,12 @@ redback-rest-api + + org.apache.maven.wagon + wagon-http + provided + + commons-validator commons-validator diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRemoteRepositoriesService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRemoteRepositoriesService.java index f19ae3201..b48bccfb2 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRemoteRepositoriesService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRemoteRepositoriesService.java @@ -19,14 +19,30 @@ package org.apache.archiva.rest.services; */ import org.apache.archiva.admin.model.RepositoryAdminException; +import org.apache.archiva.admin.model.beans.NetworkProxy; import org.apache.archiva.admin.model.beans.RemoteRepository; +import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin; import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin; +import org.apache.archiva.proxy.common.WagonFactory; +import org.apache.archiva.proxy.common.WagonFactoryException; +import org.apache.archiva.proxy.common.WagonFactoryRequest; import org.apache.archiva.rest.api.services.ArchivaRestServiceException; import org.apache.archiva.rest.api.services.RemoteRepositoriesService; import org.apache.commons.lang.StringUtils; +import org.apache.maven.wagon.ResourceDoesNotExistException; +import org.apache.maven.wagon.StreamWagon; +import org.apache.maven.wagon.TransferFailedException; +import org.apache.maven.wagon.Wagon; +import org.apache.maven.wagon.authorization.AuthorizationException; +import org.apache.maven.wagon.providers.http.AbstractHttpClientWagon; +import org.apache.maven.wagon.providers.http.HttpConfiguration; +import org.apache.maven.wagon.providers.http.HttpMethodConfiguration; import org.springframework.stereotype.Service; import javax.inject.Inject; +import javax.ws.rs.core.Response; +import java.net.MalformedURLException; +import java.net.URL; import java.util.Collections; import java.util.List; @@ -34,7 +50,7 @@ import java.util.List; * @author Olivier Lamy * @since 1.4-M1 */ -@Service ("remoteRepositoriesService#rest") +@Service( "remoteRepositoriesService#rest" ) public class DefaultRemoteRepositoriesService extends AbstractRestService implements RemoteRepositoriesService @@ -43,6 +59,13 @@ public class DefaultRemoteRepositoriesService @Inject private RemoteRepositoryAdmin remoteRepositoryAdmin; + @Inject + private WagonFactory wagonFactory; + + + @Inject + private NetworkProxyAdmin networkProxyAdmin; + public List getRemoteRepositories() throws ArchivaRestServiceException { @@ -74,7 +97,7 @@ public class DefaultRemoteRepositoriesService } public Boolean deleteRemoteRepository( String repositoryId ) - throws Exception + throws ArchivaRestServiceException { try { @@ -88,7 +111,7 @@ public class DefaultRemoteRepositoriesService } public Boolean addRemoteRepository( RemoteRepository remoteRepository ) - throws Exception + throws ArchivaRestServiceException { try { @@ -102,7 +125,7 @@ public class DefaultRemoteRepositoriesService } public Boolean updateRemoteRepository( RemoteRepository remoteRepository ) - throws Exception + throws ArchivaRestServiceException { try { @@ -115,5 +138,84 @@ public class DefaultRemoteRepositoriesService } } + @Override + public Boolean checkRemoteConnectivity( String repositoryId ) + throws ArchivaRestServiceException + { + try + { + RemoteRepository remoteRepository = remoteRepositoryAdmin.getRemoteRepository( repositoryId ); + if ( remoteRepository == null ) + { + log.warn( "ignore scheduleDownloadRemote for repo with id {} as not exists", repositoryId ); + return Boolean.FALSE; + } + NetworkProxy networkProxy = null; + if ( StringUtils.isNotBlank( remoteRepository.getRemoteDownloadNetworkProxyId() ) ) + { + networkProxy = networkProxyAdmin.getNetworkProxy( remoteRepository.getRemoteDownloadNetworkProxyId() ); + if ( networkProxy == null ) + { + log.warn( + "your remote repository is configured to download remote index trought a proxy we cannot find id:{}", + remoteRepository.getRemoteDownloadNetworkProxyId() ); + } + } + + String wagonProtocol = new URL( remoteRepository.getUrl() ).getProtocol(); + + final Wagon wagon = wagonFactory.getWagon( + new WagonFactoryRequest( wagonProtocol, remoteRepository.getExtraHeaders() ).networkProxy( + networkProxy ) ); + wagon.setReadTimeout( remoteRepository.getRemoteDownloadTimeout() * 1000 ); + wagon.setTimeout( remoteRepository.getTimeout() * 1000 ); + + if ( wagon instanceof AbstractHttpClientWagon ) + { + HttpConfiguration httpConfiguration = new HttpConfiguration(); + HttpMethodConfiguration httpMethodConfiguration = new HttpMethodConfiguration(); + httpMethodConfiguration.setUsePreemptive( true ); + httpMethodConfiguration.setReadTimeout( remoteRepository.getRemoteDownloadTimeout() * 1000 ); + httpConfiguration.setGet( httpMethodConfiguration ); + AbstractHttpClientWagon.class.cast( wagon ).setHttpConfiguration( httpConfiguration ); + } + + // we only check connectivity as remote repo can be empty + wagon.getFileList( "/" ); + + return Boolean.TRUE; + } + catch ( RepositoryAdminException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), + Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e ); + } + catch ( MalformedURLException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), + Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e ); + } + catch ( WagonFactoryException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), + Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e ); + } + catch ( TransferFailedException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), + Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e ); + } + catch ( ResourceDoesNotExistException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), + Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e ); + } + catch ( AuthorizationException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), + Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e ); + } + + } } -- 2.39.5