001package org.apache.archiva.proxy; 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.configuration.ArchivaConfiguration; 023import org.apache.archiva.configuration.NetworkProxyConfiguration; 024import org.apache.archiva.configuration.ProxyConnectorConfiguration; 025import org.apache.archiva.policies.Policy; 026import org.apache.archiva.policies.PolicyOption; 027import org.apache.archiva.policies.PolicyUtil; 028import org.apache.archiva.proxy.model.NetworkProxy; 029import org.apache.archiva.proxy.model.ProxyConnector; 030import org.apache.archiva.proxy.model.RepositoryProxyHandler; 031import org.apache.archiva.repository.base.ArchivaRepositoryRegistry; 032import org.apache.archiva.repository.ManagedRepository; 033import org.apache.archiva.repository.RemoteRepository; 034import org.apache.archiva.repository.RepositoryType; 035import org.apache.archiva.event.EventHandler; 036import org.apache.archiva.repository.event.RepositoryRegistryEvent; 037import org.slf4j.Logger; 038import org.slf4j.LoggerFactory; 039import org.springframework.stereotype.Service; 040 041import javax.annotation.PostConstruct; 042import javax.inject.Inject; 043import java.util.*; 044import java.util.function.Function; 045import java.util.stream.Collectors; 046 047/** 048 * Default proxy registry implementation. Uses the archiva configuration for accessing and storing the 049 * proxy information. 050 * 051 */ 052@SuppressWarnings( "SpringJavaInjectionPointsAutowiringInspection" ) 053@Service("proxyRegistry#default") 054public class ArchivaProxyRegistry implements ProxyRegistry, EventHandler<RepositoryRegistryEvent> { 055 056 private static final Logger log = LoggerFactory.getLogger(ArchivaProxyRegistry.class); 057 058 @Inject 059 ArchivaConfiguration archivaConfiguration; 060 061 @Inject 062 List<RepositoryProxyHandler> repositoryProxyHandlers; 063 064 @Inject 065 List<Policy> policies; 066 067 @Inject 068 ArchivaRepositoryRegistry repositoryRegistry; 069 070 private Map<String, NetworkProxy> networkProxyMap = new HashMap<>(); 071 private Map<RepositoryType, List<RepositoryProxyHandler>> handlerMap = new HashMap<>(); 072 private ProxyConnectorOrderComparator comparator = ProxyConnectorOrderComparator.getInstance(); 073 074 private Map<String, List<ProxyConnector>> connectorMap = new HashMap<>(); 075 private List<ProxyConnector> connectorList = new ArrayList<>(); 076 private Map<Policy, PolicyOption> policyMap = new HashMap<>( ); 077 078 079 @PostConstruct 080 private void init() { 081 if (repositoryProxyHandlers == null) { 082 repositoryProxyHandlers = new ArrayList<>(); 083 } 084 updateHandler(); 085 updateConnectors(); 086 updateNetworkProxies(); 087 repositoryRegistry.registerEventHandler(RepositoryRegistryEvent.RELOADED, this); 088 } 089 090 private ArchivaConfiguration getArchivaConfiguration() { 091 return archivaConfiguration; 092 } 093 094 private void updateNetworkProxies() { 095 this.networkProxyMap.clear(); 096 List<NetworkProxyConfiguration> networkProxies = getArchivaConfiguration().getConfiguration().getNetworkProxies(); 097 for (NetworkProxyConfiguration networkProxyConfig : networkProxies) { 098 String key = networkProxyConfig.getId(); 099 100 NetworkProxy proxy = new NetworkProxy(); 101 102 proxy.setProtocol(networkProxyConfig.getProtocol()); 103 proxy.setHost(networkProxyConfig.getHost()); 104 proxy.setPort(networkProxyConfig.getPort()); 105 proxy.setUsername(networkProxyConfig.getUsername()); 106 proxy.setPassword(networkProxyConfig.getPassword()==null? new char[0] : networkProxyConfig.getPassword().toCharArray()); 107 proxy.setUseNtlm(networkProxyConfig.isUseNtlm()); 108 109 this.networkProxyMap.put(key, proxy); 110 } 111 for (RepositoryProxyHandler proxyHandler : repositoryProxyHandlers) { 112 proxyHandler.setNetworkProxies(this.networkProxyMap); 113 } 114 } 115 116 private void updateHandler( ) { 117 118 for (RepositoryProxyHandler handler : repositoryProxyHandlers) { 119 List<RepositoryType> types = handler.supports(); 120 for (RepositoryType type : types) { 121 if (!handlerMap.containsKey(type)) { 122 handlerMap.put(type, new ArrayList<>()); 123 } 124 handlerMap.get(type).add(handler); 125 } 126 handler.setPolicies( policies ); 127 } 128 } 129 130 private void updateConnectors() { 131 List<ProxyConnectorConfiguration> proxyConnectorConfigurations = 132 getArchivaConfiguration().getConfiguration().getProxyConnectors(); 133 134 connectorList = proxyConnectorConfigurations.stream() 135 .map(this::buildProxyConnector) 136 .filter(Optional::isPresent) 137 .map(Optional::get) 138 .sorted(comparator).collect(Collectors.toList()); 139 connectorMap = connectorList.stream().collect(Collectors.groupingBy(a -> a.getSourceRepository().getId())); 140 for (RepositoryProxyHandler handler : repositoryProxyHandlers) { 141 handler.setProxyConnectors( connectorList ); 142 } 143 } 144 145 146 private Map<Policy, PolicyOption> getPolicyMap(ProxyConnectorConfiguration configuration) { 147 Map<String, String> policyConfig = configuration.getPolicies( ); 148 return policies.stream().collect( Collectors.toMap( Function.identity(), p -> PolicyUtil.findOption( policyConfig.get(p.getId()), p ) ) ); 149 } 150 151 private Optional<ProxyConnector> buildProxyConnector(ProxyConnectorConfiguration configuration) { 152 ProxyConnector proxyConnector = new ProxyConnector(); 153 proxyConnector.setOrder(configuration.getOrder()); 154 proxyConnector.setBlacklist(configuration.getBlackListPatterns()); 155 proxyConnector.setWhitelist(configuration.getWhiteListPatterns()); 156 if (configuration.isDisabled()) { 157 proxyConnector.disable(); 158 } else { 159 proxyConnector.enable(); 160 } 161 proxyConnector.setPolicies(getPolicyMap( configuration )); 162 proxyConnector.setProperties(configuration.getProperties()); 163 proxyConnector.setProxyId(configuration.getProxyId()); 164 ManagedRepository srcRepo = repositoryRegistry.getManagedRepository(configuration.getSourceRepoId()); 165 if (srcRepo==null) { 166 return Optional.empty(); 167 } 168 proxyConnector.setSourceRepository(srcRepo); 169 RemoteRepository targetRepo = repositoryRegistry.getRemoteRepository(configuration.getTargetRepoId()); 170 if (targetRepo==null) { 171 return Optional.empty(); 172 } 173 proxyConnector.setTargetRepository(targetRepo); 174 return Optional.of(proxyConnector); 175 } 176 177 @Override 178 public NetworkProxy getNetworkProxy(String id) { 179 return this.networkProxyMap.get(id); 180 } 181 182 @Override 183 public Map<RepositoryType, List<RepositoryProxyHandler>> getAllHandler() { 184 return this.handlerMap; 185 } 186 187 @Override 188 public List<RepositoryProxyHandler> getHandler(RepositoryType type) { 189 if (this.handlerMap.containsKey(type)) { 190 return this.handlerMap.get(type); 191 } else { 192 return new ArrayList<>(); 193 } 194 } 195 196 @Override 197 public boolean hasHandler(RepositoryType type) { 198 return this.handlerMap.containsKey(type); 199 } 200 201 202 @Override 203 public List<ProxyConnector> getProxyConnectors() { 204 return connectorList; 205 206 } 207 208 @Override 209 public Map<String, List<ProxyConnector>> getProxyConnectorAsMap() { 210 return connectorMap; 211 } 212 213 @Override 214 public void reload( ) 215 { 216 init(); 217 } 218 219 @Override 220 public void handle(RepositoryRegistryEvent event) { 221 log.debug("Reload happened, updating proxy list"); 222 if (event.getType()== RepositoryRegistryEvent.RELOADED) { 223 init(); 224 } 225 } 226}