001    package org.apache.archiva.admin.repository.proxyconnector;
002    /*
003     * Licensed to the Apache Software Foundation (ASF) under one
004     * or more contributor license agreements.  See the NOTICE file
005     * distributed with this work for additional information
006     * regarding copyright ownership.  The ASF licenses this file
007     * to you under the Apache License, Version 2.0 (the
008     * "License"); you may not use this file except in compliance
009     * with the License.  You may obtain a copy of the License at
010     *
011     *   http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing,
014     * software distributed under the License is distributed on an
015     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016     * KIND, either express or implied.  See the License for the
017     * specific language governing permissions and limitations
018     * under the License.
019     */
020    
021    import net.sf.beanlib.provider.replicator.BeanReplicator;
022    import org.apache.archiva.admin.model.AuditInformation;
023    import org.apache.archiva.admin.model.RepositoryAdminException;
024    import org.apache.archiva.admin.model.beans.ProxyConnector;
025    import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
026    import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorAdmin;
027    import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorOrderComparator;
028    import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin;
029    import org.apache.archiva.admin.repository.AbstractRepositoryAdmin;
030    import org.apache.archiva.audit.AuditEvent;
031    import org.apache.archiva.configuration.Configuration;
032    import org.apache.archiva.configuration.ProxyConnectorConfiguration;
033    import org.apache.archiva.configuration.functors.ProxyConnectorSelectionPredicate;
034    import org.apache.commons.collections.CollectionUtils;
035    import org.apache.commons.lang.StringUtils;
036    import org.springframework.stereotype.Service;
037    
038    import javax.inject.Inject;
039    import java.util.ArrayList;
040    import java.util.Collections;
041    import java.util.HashMap;
042    import java.util.Iterator;
043    import java.util.List;
044    import java.util.Map;
045    
046    /**
047     * @author Olivier Lamy
048     * @since 1.4-M1
049     */
050    @Service ( "proxyConnectorAdmin#default" )
051    public class DefaultProxyConnectorAdmin
052        extends AbstractRepositoryAdmin
053        implements ProxyConnectorAdmin
054    {
055    
056        @Inject
057        private ManagedRepositoryAdmin managedRepositoryAdmin;
058    
059        @Inject
060        private RemoteRepositoryAdmin remoteRepositoryAdmin;
061    
062        public List<ProxyConnector> getProxyConnectors()
063            throws RepositoryAdminException
064        {
065            List<ProxyConnectorConfiguration> proxyConnectorConfigurations =
066                getArchivaConfiguration().getConfiguration().getProxyConnectors();
067            List<ProxyConnector> proxyConnectors = new ArrayList<ProxyConnector>( proxyConnectorConfigurations.size() );
068            for ( ProxyConnectorConfiguration configuration : proxyConnectorConfigurations )
069            {
070                proxyConnectors.add( getProxyConnector( configuration ) );
071            }
072            Collections.sort( proxyConnectors, ProxyConnectorOrderComparator.getInstance() );
073            return proxyConnectors;
074        }
075    
076        public ProxyConnector getProxyConnector( String sourceRepoId, String targetRepoId )
077            throws RepositoryAdminException
078        {
079            for ( ProxyConnector proxyConnector : getProxyConnectors() )
080            {
081                if ( StringUtils.equals( sourceRepoId, proxyConnector.getSourceRepoId() ) && StringUtils.equals(
082                    targetRepoId, proxyConnector.getTargetRepoId() ) )
083                {
084                    return proxyConnector;
085                }
086            }
087            return null;
088        }
089    
090        public Boolean addProxyConnector( ProxyConnector proxyConnector, AuditInformation auditInformation )
091            throws RepositoryAdminException
092        {
093            if ( getProxyConnector( proxyConnector.getSourceRepoId(), proxyConnector.getTargetRepoId() ) != null )
094            {
095                throw new RepositoryAdminException(
096                    "Unable to add proxy connector, as one already exists with source repository id ["
097                        + proxyConnector.getSourceRepoId() + "] and target repository id ["
098                        + proxyConnector.getTargetRepoId() + "]." );
099            }
100    
101            validateProxyConnector( proxyConnector );
102    
103            proxyConnector.setBlackListPatterns( unescapePatterns( proxyConnector.getBlackListPatterns() ) );
104            proxyConnector.setWhiteListPatterns( unescapePatterns( proxyConnector.getWhiteListPatterns() ) );
105    
106            Configuration configuration = getArchivaConfiguration().getConfiguration();
107    
108            ProxyConnectorConfiguration proxyConnectorConfiguration = getProxyConnectorConfiguration( proxyConnector );
109            configuration.addProxyConnector( proxyConnectorConfiguration );
110            saveConfiguration( configuration );
111            triggerAuditEvent( proxyConnector.getSourceRepoId() + "-" + proxyConnector.getTargetRepoId(), null,
112                               AuditEvent.ADD_PROXY_CONNECTOR, auditInformation );
113            return Boolean.TRUE;
114    
115        }
116    
117        // FIXME take care of proxyConnectorRules !
118        public Boolean deleteProxyConnector( ProxyConnector proxyConnector, AuditInformation auditInformation )
119            throws RepositoryAdminException
120        {
121            Configuration configuration = getArchivaConfiguration().getConfiguration();
122            ProxyConnectorConfiguration proxyConnectorConfiguration =
123                findProxyConnector( proxyConnector.getSourceRepoId(), proxyConnector.getTargetRepoId(), configuration );
124            if ( proxyConnectorConfiguration == null )
125            {
126                throw new RepositoryAdminException(
127                    "unable to find ProxyConnector with source " + proxyConnector.getSourceRepoId() + " and target "
128                        + proxyConnector.getTargetRepoId() );
129            }
130            configuration.removeProxyConnector( proxyConnectorConfiguration );
131            saveConfiguration( configuration );
132            triggerAuditEvent( proxyConnector.getSourceRepoId() + "-" + proxyConnector.getTargetRepoId(), null,
133                               AuditEvent.DELETE_PROXY_CONNECTOR, auditInformation );
134            return Boolean.TRUE;
135        }
136    
137        // FIXME care take of proxyConnectorRules !
138        public Boolean updateProxyConnector( ProxyConnector proxyConnector, AuditInformation auditInformation )
139            throws RepositoryAdminException
140        {
141            Configuration configuration = getArchivaConfiguration().getConfiguration();
142            ProxyConnectorConfiguration proxyConnectorConfiguration =
143                findProxyConnector( proxyConnector.getSourceRepoId(), proxyConnector.getTargetRepoId(), configuration );
144            configuration.removeProxyConnector( proxyConnectorConfiguration );
145            configuration.addProxyConnector( getProxyConnectorConfiguration( proxyConnector ) );
146            saveConfiguration( configuration );
147            triggerAuditEvent( proxyConnector.getSourceRepoId() + "-" + proxyConnector.getTargetRepoId(), null,
148                               AuditEvent.MODIFY_PROXY_CONNECTOR, auditInformation );
149            return Boolean.TRUE;
150        }
151    
152        protected List<String> unescapePatterns( List<String> patterns )
153        {
154            if ( patterns != null )
155            {
156                List<String> rawPatterns = new ArrayList<String>( patterns.size() );
157                for ( String pattern : patterns )
158                {
159                    rawPatterns.add( StringUtils.replace( pattern, "\\\\", "\\" ) );
160                }
161                return rawPatterns;
162            }
163    
164            return Collections.emptyList();
165        }
166    
167        public Map<String, List<ProxyConnector>> getProxyConnectorAsMap()
168            throws RepositoryAdminException
169        {
170            Map<String, List<ProxyConnector>> proxyConnectorMap = new HashMap<String, java.util.List<ProxyConnector>>();
171    
172            Iterator<ProxyConnector> it = getProxyConnectors().iterator();
173            while ( it.hasNext() )
174            {
175                ProxyConnector proxyConfig = it.next();
176                String key = proxyConfig.getSourceRepoId();
177    
178                List<ProxyConnector> connectors = proxyConnectorMap.get( key );
179                if ( connectors == null )
180                {
181                    connectors = new ArrayList<ProxyConnector>( 1 );
182                    proxyConnectorMap.put( key, connectors );
183                }
184    
185                connectors.add( proxyConfig );
186    
187                Collections.sort( connectors, ProxyConnectorOrderComparator.getInstance() );
188            }
189    
190            return proxyConnectorMap;
191        }
192    
193        private ProxyConnectorConfiguration findProxyConnector( String sourceId, String targetId,
194                                                                Configuration configuration )
195        {
196            if ( StringUtils.isBlank( sourceId ) )
197            {
198                return null;
199            }
200    
201            if ( StringUtils.isBlank( targetId ) )
202            {
203                return null;
204            }
205    
206            ProxyConnectorSelectionPredicate selectedProxy = new ProxyConnectorSelectionPredicate( sourceId, targetId );
207            return (ProxyConnectorConfiguration) CollectionUtils.find( configuration.getProxyConnectors(), selectedProxy );
208        }
209    
210        protected ProxyConnectorConfiguration getProxyConnectorConfiguration( ProxyConnector proxyConnector )
211        {
212            return proxyConnector == null
213                ? null
214                : new BeanReplicator().replicateBean( proxyConnector, ProxyConnectorConfiguration.class );
215        }
216    
217        protected ProxyConnector getProxyConnector( ProxyConnectorConfiguration proxyConnectorConfiguration )
218        {
219            return proxyConnectorConfiguration == null
220                ? null
221                : new BeanReplicator().replicateBean( proxyConnectorConfiguration, ProxyConnector.class );
222        }
223    
224        protected void validateProxyConnector( ProxyConnector proxyConnector )
225            throws RepositoryAdminException
226        {
227            // validate source a Managed target a Remote
228            if ( managedRepositoryAdmin.getManagedRepository( proxyConnector.getSourceRepoId() ) == null )
229            {
230                throw new RepositoryAdminException(
231                    "non valid ProxyConnector sourceRepo with id " + proxyConnector.getSourceRepoId()
232                        + " is not a ManagedRepository" );
233            }
234            if ( remoteRepositoryAdmin.getRemoteRepository( proxyConnector.getTargetRepoId() ) == null )
235            {
236                throw new RepositoryAdminException(
237                    "non valid ProxyConnector sourceRepo with id " + proxyConnector.getTargetRepoId()
238                        + " is not a RemoteRepository" );
239            }
240    
241            // FIXME validate NetworkProxyConfiguration too when available
242        }
243    }