001package org.apache.archiva.rest.services; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.archiva.admin.model.RepositoryAdminException; 023import org.apache.archiva.admin.model.beans.NetworkProxy; 024import org.apache.archiva.admin.model.beans.RemoteRepository; 025import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin; 026import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin; 027import org.apache.archiva.proxy.common.WagonFactory; 028import org.apache.archiva.proxy.common.WagonFactoryRequest; 029import org.apache.archiva.rest.api.services.ArchivaRestServiceException; 030import org.apache.archiva.rest.api.services.RemoteRepositoriesService; 031import org.apache.commons.lang.StringUtils; 032import org.apache.maven.wagon.TransferFailedException; 033import org.apache.maven.wagon.Wagon; 034import org.apache.maven.wagon.providers.http.AbstractHttpClientWagon; 035import org.apache.maven.wagon.providers.http.HttpConfiguration; 036import org.apache.maven.wagon.providers.http.HttpMethodConfiguration; 037import org.apache.maven.wagon.proxy.ProxyInfo; 038import org.apache.maven.wagon.repository.Repository; 039import org.springframework.stereotype.Service; 040 041import javax.annotation.PostConstruct; 042import javax.inject.Inject; 043import javax.ws.rs.core.Response; 044import java.net.URL; 045import java.util.Collections; 046import java.util.HashMap; 047import java.util.List; 048import java.util.Map; 049 050/** 051 * @author Olivier Lamy 052 * @since 1.4-M1 053 */ 054@Service( "remoteRepositoriesService#rest" ) 055public class DefaultRemoteRepositoriesService 056 extends AbstractRestService 057 implements RemoteRepositoriesService { 058 059 @Inject 060 private RemoteRepositoryAdmin remoteRepositoryAdmin; 061 062 @Inject 063 private WagonFactory wagonFactory; 064 065 066 @Inject 067 private NetworkProxyAdmin networkProxyAdmin; 068 069 int checkReadTimeout = 10000; 070 int checkTimeout = 9000; 071 072 073 @Override 074 public List<RemoteRepository> getRemoteRepositories() 075 throws ArchivaRestServiceException { 076 try { 077 List<RemoteRepository> remoteRepositories = remoteRepositoryAdmin.getRemoteRepositories(); 078 return remoteRepositories == null ? Collections.<RemoteRepository>emptyList() : remoteRepositories; 079 } catch (RepositoryAdminException e) { 080 log.error(e.getMessage(), e); 081 throw new ArchivaRestServiceException(e.getMessage(), e.getFieldName(), e); 082 } 083 } 084 085 @Override 086 public RemoteRepository getRemoteRepository(String repositoryId) 087 throws ArchivaRestServiceException { 088 089 List<RemoteRepository> remoteRepositories = getRemoteRepositories(); 090 for (RemoteRepository repository : remoteRepositories) { 091 if (StringUtils.equals(repositoryId, repository.getId())) { 092 return repository; 093 } 094 } 095 return null; 096 } 097 098 @Override 099 public Boolean deleteRemoteRepository(String repositoryId) 100 throws ArchivaRestServiceException { 101 try { 102 return remoteRepositoryAdmin.deleteRemoteRepository(repositoryId, getAuditInformation()); 103 } catch (RepositoryAdminException e) { 104 log.error(e.getMessage(), e); 105 throw new ArchivaRestServiceException(e.getMessage(), e.getFieldName(), e); 106 } 107 } 108 109 @Override 110 public Boolean addRemoteRepository(RemoteRepository remoteRepository) 111 throws ArchivaRestServiceException { 112 try { 113 return remoteRepositoryAdmin.addRemoteRepository(remoteRepository, getAuditInformation()); 114 } catch (RepositoryAdminException e) { 115 log.error(e.getMessage(), e); 116 throw new ArchivaRestServiceException(e.getMessage(), e.getFieldName(), e); 117 } 118 } 119 120 @Override 121 public Boolean updateRemoteRepository(RemoteRepository remoteRepository) 122 throws ArchivaRestServiceException { 123 try { 124 return remoteRepositoryAdmin.updateRemoteRepository(remoteRepository, getAuditInformation()); 125 } catch (RepositoryAdminException e) { 126 log.error(e.getMessage(), e); 127 throw new ArchivaRestServiceException(e.getMessage(), e.getFieldName(), e); 128 } 129 } 130 131 @Override 132 public Boolean checkRemoteConnectivity(String repositoryId) 133 throws ArchivaRestServiceException { 134 try { 135 RemoteRepository remoteRepository = remoteRepositoryAdmin.getRemoteRepository(repositoryId); 136 if (remoteRepository == null) { 137 log.warn("ignore scheduleDownloadRemote for repo with id {} as not exists", repositoryId); 138 return Boolean.FALSE; 139 } 140 NetworkProxy networkProxy = null; 141 if (StringUtils.isNotBlank(remoteRepository.getRemoteDownloadNetworkProxyId())) { 142 networkProxy = networkProxyAdmin.getNetworkProxy(remoteRepository.getRemoteDownloadNetworkProxyId()); 143 if (networkProxy == null) { 144 log.warn( 145 "your remote repository is configured to download remote index trought a proxy we cannot find id:{}", 146 remoteRepository.getRemoteDownloadNetworkProxyId()); 147 } 148 } 149 150 String wagonProtocol = new URL(remoteRepository.getUrl()).getProtocol(); 151 152 final Wagon wagon = 153 wagonFactory.getWagon(new WagonFactoryRequest(wagonProtocol, remoteRepository.getExtraHeaders()) // 154 .networkProxy(networkProxy)); 155 156 // hardcoded value as it's a check of the remote repo connectivity 157 wagon.setReadTimeout(checkReadTimeout); 158 wagon.setTimeout(checkTimeout); 159 160 if (wagon instanceof AbstractHttpClientWagon) { 161 HttpMethodConfiguration httpMethodConfiguration = new HttpMethodConfiguration() // 162 .setUsePreemptive(true) // 163 .setReadTimeout(checkReadTimeout); 164 HttpConfiguration httpConfiguration = new HttpConfiguration().setGet(httpMethodConfiguration); 165 AbstractHttpClientWagon.class.cast(wagon).setHttpConfiguration(httpConfiguration); 166 } 167 168 ProxyInfo proxyInfo = null; 169 if (networkProxy != null) { 170 proxyInfo = new ProxyInfo(); 171 proxyInfo.setType(networkProxy.getProtocol()); 172 proxyInfo.setHost(networkProxy.getHost()); 173 proxyInfo.setPort(networkProxy.getPort()); 174 proxyInfo.setUserName(networkProxy.getUsername()); 175 proxyInfo.setPassword(networkProxy.getPassword()); 176 } 177 String url = StringUtils.stripEnd(remoteRepository.getUrl(), "/"); 178 wagon.connect(new Repository(remoteRepository.getId(), url), proxyInfo); 179 180 // MRM-1933, there are certain servers that do not allow browsing 181 if (!(StringUtils.isEmpty(remoteRepository.getCheckPath()) || 182 "/".equals(remoteRepository.getCheckPath()))) { 183 return wagon.resourceExists(remoteRepository.getCheckPath()); 184 } else { 185 // we only check connectivity as remote repo can be empty 186 // MRM-1909: Wagon implementation appends a slash already 187 wagon.getFileList(""); 188 } 189 190 return Boolean.TRUE; 191 } catch (TransferFailedException e) { 192 log.info("TransferFailedException :{}", e.getMessage()); 193 return Boolean.FALSE; 194 } catch (Exception e) { 195 // This service returns either true or false, Exception cannot be handled by the clients 196 log.debug("Exception occured on connectivity test.", e); 197 log.info("Connection exception: {}", e.getMessage()); 198 return Boolean.FALSE; 199 } 200 201 } 202 203 public int getCheckReadTimeout() { 204 return checkReadTimeout; 205 } 206 207 public void setCheckReadTimeout(int checkReadTimeout) { 208 this.checkReadTimeout = checkReadTimeout; 209 } 210 211 public int getCheckTimeout() { 212 return checkTimeout; 213 } 214 215 public void setCheckTimeout(int checkTimeout) { 216 this.checkTimeout = checkTimeout; 217 } 218 219}