Browse Source

[MRM-482] Saving a proxy connector after adding a new property results to HTTP 500 error

[MRM-477] Missing ability to manage proxy order.
[MRM-437] admin editing of proxy connectors fails in multiple instances
* Split giant ball of mud ConfigureProxyConnectorAction into seperate Add/Edit/Delete/Sort/List actions
* Added ability to maintain sort order.
* Added unit testing.
* Cleaned up Proxy Connector admin UI to allow for extra long Location / URL paths.
* Slideout Hide of the Advanced configuration options on the Proxy Connector list screen.



git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@582020 13f79535-47bb-0310-9956-ffa450edef68
tags/archiva-1.0-beta-3
Joakim Erdfelt 16 years ago
parent
commit
42336da5e3
41 changed files with 3601 additions and 1272 deletions
  1. 40
    13
      archiva-base/archiva-configuration/src/main/java/org/apache/maven/archiva/configuration/DefaultArchivaConfiguration.java
  2. 73
    0
      archiva-base/archiva-configuration/src/main/java/org/apache/maven/archiva/configuration/functors/ProxyConnectorConfigurationOrderComparator.java
  3. 51
    11
      archiva-base/archiva-configuration/src/main/mdo/configuration.mdo
  4. 131
    0
      archiva-base/archiva-configuration/src/test/java/org/apache/maven/archiva/configuration/functors/ProxyConnectorConfigurationOrderComparatorTest.java
  5. 1
    1
      archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/DownloadPolicy.java
  6. 80
    98
      archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java
  7. 23
    11
      archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/ProxyConnector.java
  8. 71
    0
      archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/ProxyConnectorOrderComparator.java
  9. 1
    1
      archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/RepositoryProxyConnectors.java
  10. 2
    5
      archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/AbstractProxyTestCase.java
  11. 2
    5
      archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/MockConfiguration.java
  12. 1
    1
      archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/WagonDelegate.java
  13. 4
    0
      archiva-web/archiva-webapp/pom.xml
  14. 1
    1
      archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/appearance/AbstractAppearanceAction.java
  15. 137
    0
      archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/AbstractProxyConnectorAction.java
  16. 432
    0
      archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/AbstractProxyConnectorFormAction.java
  17. 81
    0
      archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/AddProxyConnectorAction.java
  18. 0
    576
      archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/ConfigureProxyConnectorAction.java
  19. 106
    0
      archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/DeleteProxyConnectorAction.java
  20. 114
    0
      archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/EditProxyConnectorAction.java
  21. 11
    57
      archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/ProxyConnectorsAction.java
  22. 0
    56
      archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/SingleSelectTransformer.java
  23. 136
    0
      archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/SortProxyConnectorsAction.java
  24. 8
    8
      archiva-web/archiva-webapp/src/main/resources/xwork.xml
  25. 45
    0
      archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/addProxyConnector.jsp
  26. 9
    249
      archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/editProxyConnector.jsp
  27. 256
    0
      archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/include/proxyConnectorForm.jspf
  28. 68
    37
      archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/proxyConnectors.jsp
  29. 39
    29
      archiva-web/archiva-webapp/src/main/webapp/css/site.css
  30. BIN
      archiva-web/archiva-webapp/src/main/webapp/images/icons/down.gif
  31. BIN
      archiva-web/archiva-webapp/src/main/webapp/images/icons/up.gif
  32. 128
    0
      archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/AbstractWebworkTestCase.java
  33. 408
    0
      archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/AddProxyConnectorActionTest.java
  34. 0
    95
      archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/ConfigureProxyConnectorActionTest.java
  35. 225
    0
      archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/DeleteProxyConnectorActionTest.java
  36. 436
    0
      archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/EditProxyConnectorActionTest.java
  37. 151
    0
      archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/ProxyConnectorsActionTest.java
  38. 253
    0
      archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/SortProxyConnectorsActionTest.java
  39. 6
    2
      archiva-web/archiva-webapp/src/test/resources/log4j.xml
  40. 21
    16
      archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/action/admin/connectors/proxy/AddProxyConnectorActionTest.xml
  41. 50
    0
      archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/action/admin/connectors/proxy/EditProxyConnectorActionTest.xml

+ 40
- 13
archiva-base/archiva-configuration/src/main/java/org/apache/maven/archiva/configuration/DefaultArchivaConfiguration.java View File

@@ -20,6 +20,7 @@ package org.apache.maven.archiva.configuration;
*/

import org.apache.commons.io.FileUtils;
import org.apache.maven.archiva.configuration.functors.ProxyConnectorConfigurationOrderComparator;
import org.apache.maven.archiva.configuration.io.registry.ConfigurationRegistryReader;
import org.apache.maven.archiva.configuration.io.registry.ConfigurationRegistryWriter;
import org.codehaus.plexus.logging.AbstractLogEnabled;
@@ -33,9 +34,11 @@ import org.codehaus.plexus.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
* Implementation of configuration holder that retrieves it from the registry.
@@ -145,7 +148,28 @@ public class DefaultArchivaConfiguration
}
}
}

// Normalize the order fields in the proxy connectors.
if ( !config.getProxyConnectors().isEmpty() )
{
Map<String, java.util.List<ProxyConnectorConfiguration>> proxyConnectorMap = config
.getProxyConnectorAsMap();

for ( String key : proxyConnectorMap.keySet() )
{
List<ProxyConnectorConfiguration> connectors = proxyConnectorMap.get( key );
// Sort connectors by order field.
Collections.sort( connectors, ProxyConnectorConfigurationOrderComparator.getInstance() );

// Normalize the order field values.
int order = 1;
for ( ProxyConnectorConfiguration connector : connectors )
{
connector.setOrder( order++ );
}
}
}

return config;
}

@@ -161,7 +185,8 @@ public class DefaultArchivaConfiguration
catch ( RegistryException e )
{
throw new ConfigurationRuntimeException(
"Fatal error: Unable to find the built-in default configuration and load it into the registry", e );
"Fatal error: Unable to find the built-in default configuration and load it into the registry",
e );
}
return registry.getSubset( KEY );
}
@@ -189,10 +214,10 @@ public class DefaultArchivaConfiguration

// a little aggressive with the repositoryScanning and databaseScanning - should be no need to split
// that configuration
if ( key.startsWith( "repositories" ) || key.startsWith( "proxyConnectors" ) ||
key.startsWith( "networkProxies" ) || key.startsWith( "repositoryScanning" ) ||
key.startsWith( "databaseScanning" ) || key.startsWith( "remoteRepositories" ) ||
key.startsWith( "managedRepositories" ) )
if ( key.startsWith( "repositories" ) || key.startsWith( "proxyConnectors" )
|| key.startsWith( "networkProxies" ) || key.startsWith( "repositoryScanning" )
|| key.startsWith( "databaseScanning" ) || key.startsWith( "remoteRepositories" )
|| key.startsWith( "managedRepositories" ) )
{
foundList = true;
}
@@ -203,12 +228,13 @@ public class DefaultArchivaConfiguration
this.configuration = null;

throw new IndeterminateConfigurationException(
"Configuration can not be saved when it is loaded from two sources" );
"Configuration can not be saved when it is loaded from two sources" );
}
}

// escape all cron expressions to handle ','
for ( Iterator<ManagedRepositoryConfiguration> i = configuration.getManagedRepositories().iterator(); i.hasNext(); )
for ( Iterator<ManagedRepositoryConfiguration> i = configuration.getManagedRepositories().iterator(); i
.hasNext(); )
{
ManagedRepositoryConfiguration c = i.next();
c.setRefreshCronExpression( escapeCronExpression( c.getRefreshCronExpression() ) );
@@ -217,7 +243,8 @@ public class DefaultArchivaConfiguration
if ( configuration.getDatabaseScanning() != null )
{
configuration.getDatabaseScanning().setCronExpression(
escapeCronExpression( configuration.getDatabaseScanning().getCronExpression() ) );
escapeCronExpression( configuration
.getDatabaseScanning().getCronExpression() ) );
}

new ConfigurationRegistryWriter().write( configuration, section );
@@ -299,10 +326,10 @@ public class DefaultArchivaConfiguration

private String removeExpressions( String directory )
{
String value = StringUtils.replace( directory, "${appserver.base}",
registry.getString( "appserver.base", "${appserver.base}" ) );
value = StringUtils.replace( value, "${appserver.home}",
registry.getString( "appserver.home", "${appserver.home}" ) );
String value = StringUtils.replace( directory, "${appserver.base}", registry.getString( "appserver.base",
"${appserver.base}" ) );
value = StringUtils.replace( value, "${appserver.home}", registry.getString( "appserver.home",
"${appserver.home}" ) );
return value;
}


+ 73
- 0
archiva-base/archiva-configuration/src/main/java/org/apache/maven/archiva/configuration/functors/ProxyConnectorConfigurationOrderComparator.java View File

@@ -0,0 +1,73 @@
package org.apache.maven.archiva.configuration.functors;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;

import java.util.Comparator;

/**
* ProxyConnectorConfigurationOrderComparator
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ProxyConnectorConfigurationOrderComparator
implements Comparator<ProxyConnectorConfiguration>
{
private static ProxyConnectorConfigurationOrderComparator INSTANCE = new ProxyConnectorConfigurationOrderComparator();
public int compare( ProxyConnectorConfiguration o1, ProxyConnectorConfiguration o2 )
{
if ( o1 == null && o2 == null )
{
return 0;
}

// Ensure null goes to end of list.
if ( o1 == null && o2 != null )
{
return 1;
}

if ( o1 != null && o2 == null )
{
return -1;
}

// Ensure 0 (unordered) goes to end of list.
if ( o1.getOrder() == 0 && o2.getOrder() != 0 )
{
return 1;
}
if ( o1.getOrder() != 0 && o2.getOrder() == 0 )
{
return -1;
}

return o1.getOrder() - o2.getOrder();
}

public static ProxyConnectorConfigurationOrderComparator getInstance()
{
return INSTANCE;
}
}

+ 51
- 11
archiva-base/archiva-configuration/src/main/mdo/configuration.mdo View File

@@ -141,23 +141,49 @@
java.util.Map<String, NetworkProxyConfiguration> map = new java.util.HashMap<String, NetworkProxyConfiguration>();
if ( networkProxies != null )
{
for ( java.util.Iterator i = networkProxies.iterator(); i.hasNext(); )
for ( java.util.Iterator<NetworkProxyConfiguration> i = networkProxies.iterator(); i.hasNext(); )
{
NetworkProxyConfiguration proxy = (NetworkProxyConfiguration) i.next();
NetworkProxyConfiguration proxy = i.next();
map.put( proxy.getId(), proxy );
}
}
return map;
}
}
public java.util.Map<String, java.util.List<ProxyConnectorConfiguration>> getProxyConnectorAsMap()
{
java.util.Map<String, java.util.List<ProxyConnectorConfiguration>> proxyConnectorMap =
new java.util.HashMap<String, java.util.List<ProxyConnectorConfiguration>>();

java.util.Iterator<ProxyConnectorConfiguration> it = proxyConnectors.iterator();
while ( it.hasNext() )
{
ProxyConnectorConfiguration proxyConfig = it.next();
String key = proxyConfig.getSourceRepoId();

java.util.List<ProxyConnectorConfiguration> connectors = proxyConnectorMap.get( key );
if ( connectors == null )
{
connectors = new java.util.ArrayList<ProxyConnectorConfiguration>();
proxyConnectorMap.put( key, connectors );
}

connectors.add( proxyConfig );
java.util.Collections.sort( connectors,
org.apache.maven.archiva.configuration.functors.ProxyConnectorConfigurationOrderComparator.getInstance() );
}

return proxyConnectorMap;
}
public java.util.Map<String, RemoteRepositoryConfiguration> getRemoteRepositoriesAsMap()
{
java.util.Map<String, RemoteRepositoryConfiguration> map = new java.util.HashMap<String, RemoteRepositoryConfiguration>();
if ( remoteRepositories != null )
{
for ( java.util.Iterator i = remoteRepositories.iterator(); i.hasNext(); )
for ( java.util.Iterator<RemoteRepositoryConfiguration> i = remoteRepositories.iterator(); i.hasNext(); )
{
RemoteRepositoryConfiguration repo = (RemoteRepositoryConfiguration) i.next();
RemoteRepositoryConfiguration repo = i.next();
map.put( repo.getId(), repo );
}
}
@@ -168,9 +194,9 @@
{
if ( remoteRepositories != null )
{
for ( java.util.Iterator i = remoteRepositories.iterator(); i.hasNext(); )
for ( java.util.Iterator<RemoteRepositoryConfiguration> i = remoteRepositories.iterator(); i.hasNext(); )
{
RemoteRepositoryConfiguration repo = (RemoteRepositoryConfiguration) i.next();
RemoteRepositoryConfiguration repo = i.next();
if ( repo.getId().equals( id ) )
{
return repo;
@@ -185,9 +211,9 @@
java.util.Map<String, ManagedRepositoryConfiguration> map = new java.util.HashMap<String, ManagedRepositoryConfiguration>();
if ( managedRepositories != null )
{
for ( java.util.Iterator i = managedRepositories.iterator(); i.hasNext(); )
for ( java.util.Iterator<ManagedRepositoryConfiguration> i = managedRepositories.iterator(); i.hasNext(); )
{
ManagedRepositoryConfiguration repo = (ManagedRepositoryConfiguration) i.next();
ManagedRepositoryConfiguration repo = i.next();
map.put( repo.getId(), repo );
}
}
@@ -198,9 +224,9 @@
{
if ( managedRepositories != null )
{
for ( java.util.Iterator i = managedRepositories.iterator(); i.hasNext(); )
for ( java.util.Iterator<ManagedRepositoryConfiguration> i = managedRepositories.iterator(); i.hasNext(); )
{
ManagedRepositoryConfiguration repo = (ManagedRepositoryConfiguration) i.next();
ManagedRepositoryConfiguration repo = i.next();
if ( repo.getId().equals( id ) )
{
return repo;
@@ -517,11 +543,25 @@
<name>ProxyConnectorConfiguration</name>
<version>1.0.0+</version>
<fields>
<field>
<name>order</name>
<version>1.0.0+</version>
<description>
The order of the proxy connectors. (0 means no order specified)
</description>
<type>int</type>
<defaultValue>0</defaultValue>
</field>
</fields>
<codeSegments>
<codeSegment>
<version>1.0.0+</version>
<code><![CDATA[
/**
* The order id for UNORDERED
*/
public static final int UNORDERED = 0;
/**
* The policy key {@link #getPolicies()} for snapshot handling.
* See {@link org.apache.maven.archiva.policies.SnapshotsPolicy}

+ 131
- 0
archiva-base/archiva-configuration/src/test/java/org/apache/maven/archiva/configuration/functors/ProxyConnectorConfigurationOrderComparatorTest.java View File

@@ -0,0 +1,131 @@
package org.apache.maven.archiva.configuration.functors;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import junit.framework.TestCase;

/**
* ProxyConnectorConfigurationOrderComparatorTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ProxyConnectorConfigurationOrderComparatorTest
extends TestCase
{
public void testSortOfAllZeros()
{
List<ProxyConnectorConfiguration> proxies = new ArrayList<ProxyConnectorConfiguration>();

proxies.add( createConnector( "corporate", 0 ) );
proxies.add( createConnector( "snapshots", 0 ) );
proxies.add( createConnector( "3rdparty", 0 ) );
proxies.add( createConnector( "sandbox", 0 ) );

Collections.sort( proxies, ProxyConnectorConfigurationOrderComparator.getInstance() );

assertProxyOrder( new String[] { "corporate", "snapshots", "3rdparty", "sandbox" }, proxies );
}

public void testSortNormal()
{
List<ProxyConnectorConfiguration> proxies = new ArrayList<ProxyConnectorConfiguration>();

proxies.add( createConnector( "corporate", 3 ) );
proxies.add( createConnector( "snapshots", 1 ) );
proxies.add( createConnector( "3rdparty", 2 ) );
proxies.add( createConnector( "sandbox", 4 ) );

Collections.sort( proxies, new ProxyConnectorConfigurationOrderComparator() );

assertProxyOrder( new String[] { "snapshots", "3rdparty", "corporate", "sandbox" }, proxies );
}

public void testSortPartial()
{
List<ProxyConnectorConfiguration> proxies = new ArrayList<ProxyConnectorConfiguration>();

proxies.add( createConnector( "corporate", 3 ) );
proxies.add( createConnector( "snapshots", 0 ) );
proxies.add( createConnector( "3rdparty", 2 ) );
proxies.add( createConnector( "sandbox", 0 ) );

Collections.sort( proxies, new ProxyConnectorConfigurationOrderComparator() );

assertProxyOrder( new String[] { "3rdparty", "corporate", "snapshots", "sandbox" }, proxies );
}

private void assertProxyOrder( String[] ids, List<ProxyConnectorConfiguration> proxies )
{
assertEquals( "Proxies.size() == ids.length", ids.length, proxies.size() );

int orderFailedAt = -1;

for ( int i = 0; i < ids.length; i++ )
{
if ( !StringUtils.equals( ids[i], proxies.get( i ).getProxyId() ) )
{
orderFailedAt = i;
break;
}
}

if ( orderFailedAt >= 0 )
{
StringBuffer msg = new StringBuffer();

msg.append( "Failed expected order of the proxies <" );
msg.append( StringUtils.join( ids, ", " ) );
msg.append( ">, actual <" );

boolean needsComma = false;
for ( ProxyConnectorConfiguration proxy : proxies )
{
if ( needsComma )
{
msg.append( ", " );
}
msg.append( proxy.getProxyId() );
needsComma = true;
}
msg.append( "> failure at index <" ).append( orderFailedAt ).append( ">." );

fail( msg.toString() );
}
}

private ProxyConnectorConfiguration createConnector( String id, int order )
{
ProxyConnectorConfiguration proxy = new ProxyConnectorConfiguration();
proxy.setProxyId( id );
proxy.setOrder( order );
proxy.setSourceRepoId( id + "_m" );
proxy.setTargetRepoId( id + "_r" );

return proxy;
}
}

+ 1
- 1
archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/DownloadPolicy.java View File

@@ -44,7 +44,7 @@ public interface DownloadPolicy
*
* @return the list of options for this policy.
*/
public List getOptions();
public List<String> getOptions();

/**
* Get the default option for this policy.

+ 80
- 98
archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java View File

@@ -19,6 +19,7 @@ package org.apache.maven.archiva.proxy;
* under the License.
*/

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
@@ -32,6 +33,8 @@ import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.ProjectReference;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.policies.DownloadPolicy;
import org.apache.maven.archiva.policies.PostDownloadPolicy;
import org.apache.maven.archiva.policies.PreDownloadPolicy;
import org.apache.maven.archiva.policies.urlcache.UrlFailureCache;
import org.apache.maven.archiva.repository.ArchivaConfigurationAdaptor;
import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayout;
@@ -58,14 +61,12 @@ import org.codehaus.plexus.util.SelectorUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Map.Entry;

/**
* DefaultRepositoryProxyConnectors
@@ -86,7 +87,7 @@ public class DefaultRepositoryProxyConnectors
/**
* @plexus.requirement role="org.apache.maven.wagon.Wagon"
*/
private Map/*<String,Wagon>*/wagons;
private Map<String, Wagon> wagons;

/**
* @plexus.requirement
@@ -101,21 +102,21 @@ public class DefaultRepositoryProxyConnectors
/**
* @plexus.requirement role="org.apache.maven.archiva.policies.PreDownloadPolicy"
*/
private Map preDownloadPolicies;
private Map<String, PreDownloadPolicy> preDownloadPolicies;

/**
* @plexus.requirement role="org.apache.maven.archiva.policies.PostDownloadPolicy"
*/
private Map postDownloadPolicies;
private Map<String, PostDownloadPolicy> postDownloadPolicies;

/**
* @plexus.requirement role-hint="default"
*/
private UrlFailureCache urlFailureCache;

private Map proxyConnectorMap = new HashMap();
private Map<String, List<ProxyConnector>> proxyConnectorMap = new HashMap<String, List<ProxyConnector>>();

private Map networkProxyMap = new HashMap();
private Map<String, ProxyInfo> networkProxyMap = new HashMap<String, ProxyInfo>();

/**
* @plexus.requirement
@@ -139,11 +140,9 @@ public class DefaultRepositoryProxyConnectors
Properties requestProperties = new Properties();
requestProperties.setProperty( "version", artifact.getVersion() );

List connectors = getProxyConnectors( repository );
Iterator it = connectors.iterator();
while ( it.hasNext() )
List<ProxyConnector> connectors = getProxyConnectors( repository );
for( ProxyConnector connector: connectors )
{
ProxyConnector connector = (ProxyConnector) it.next();
ArchivaRepository targetRepository = connector.getTargetRepository();
String targetPath = getLayout( targetRepository ).toPath( artifact );

@@ -172,17 +171,15 @@ public class DefaultRepositoryProxyConnectors
Properties requestProperties = new Properties();
boolean hasFetched = false;

List connectors = getProxyConnectors( repository );
Iterator it = connectors.iterator();
while ( it.hasNext() )
List<ProxyConnector> connectors = getProxyConnectors( repository );
for( ProxyConnector connector: connectors )
{
ProxyConnector connector = (ProxyConnector) it.next();
ArchivaRepository targetRepository = connector.getTargetRepository();
String targetPath = metadataTools.toPath( metadata );

File localRepoFile = toLocalRepoFile( repository, targetRepository, targetPath );
File downloadedFile =
transferFile( connector, targetRepository, targetPath, localRepoFile, requestProperties );
File downloadedFile = transferFile( connector, targetRepository, targetPath, localRepoFile,
requestProperties );

if ( fileExists( downloadedFile ) )
{
@@ -237,17 +234,15 @@ public class DefaultRepositoryProxyConnectors
Properties requestProperties = new Properties();
boolean hasFetched = false;

List connectors = getProxyConnectors( repository );
Iterator it = connectors.iterator();
while ( it.hasNext() )
List<ProxyConnector> connectors = getProxyConnectors( repository );
for( ProxyConnector connector: connectors )
{
ProxyConnector connector = (ProxyConnector) it.next();
ArchivaRepository targetRepository = connector.getTargetRepository();
String targetPath = metadataTools.toPath( metadata );

File localRepoFile = toLocalRepoFile( repository, targetRepository, targetPath );
File downloadedFile =
transferFile( connector, targetRepository, targetPath, localRepoFile, requestProperties );
File downloadedFile = transferFile( connector, targetRepository, targetPath, localRepoFile,
requestProperties );

if ( fileExists( downloadedFile ) )
{
@@ -345,8 +340,8 @@ public class DefaultRepositoryProxyConnectors
}
catch ( LayoutException e )
{
throw new ProxyException( "Unable to proxy due to bad repository layout definition [" + repository.getId() +
"] had a layout defined as [" + repository.getLayoutType() + "] : " + e.getMessage(), e );
throw new ProxyException( "Unable to proxy due to bad repository layout definition [" + repository.getId()
+ "] had a layout defined as [" + repository.getLayoutType() + "] : " + e.getMessage(), e );
}
}

@@ -395,7 +390,7 @@ public class DefaultRepositoryProxyConnectors
requestProperties.setProperty( "url", url );

// Is a whitelist defined?
if ( !isEmpty( connector.getWhitelist() ) )
if ( CollectionUtils.isNotEmpty( connector.getWhitelist() ) )
{
// Path must belong to whitelist.
if ( !matchesPattern( remotePath, connector.getWhitelist() ) )
@@ -442,8 +437,8 @@ public class DefaultRepositoryProxyConnectors

transferChecksum( wagon, remoteRepository, remotePath, localFile, ".sha1" );
transferChecksum( wagon, remoteRepository, remotePath, localFile, ".md5" );
}
}
}
catch ( ResourceDoesNotExistException e )
{
@@ -542,8 +537,7 @@ public class DefaultRepositoryProxyConnectors
* @throws ProxyException if there was a problem moving the downloaded file into place.
* @throws WagonException if there was a problem tranfering the file.
*/
private File transferSimpleFile( Wagon wagon, ArchivaRepository remoteRepository, String remotePath,
File localFile )
private File transferSimpleFile( Wagon wagon, ArchivaRepository remoteRepository, String remotePath, File localFile )
throws ProxyException, WagonException
{
assert ( remotePath != null );
@@ -578,7 +572,8 @@ public class DefaultRepositoryProxyConnectors
if ( !success )
{
getLogger().info(
"Not downloaded, as local file is newer than remote side: " + localFile.getAbsolutePath() );
"Not downloaded, as local file is newer than remote side: "
+ localFile.getAbsolutePath() );
}
else if ( temp.exists() )
{
@@ -617,14 +612,12 @@ public class DefaultRepositoryProxyConnectors
* @param localFile the local file (utilized by the {@link DownloadPolicy#applyPolicy(String,Properties,File)})
* @return true if all of the policies passed, false if a policy failed.
*/
private boolean applyPolicies( Map policies, Map settings, Properties request, File localFile )
private boolean applyPolicies( Map<String, ? extends DownloadPolicy> policies, Map<String, String> settings, Properties request, File localFile )
{
Iterator it = policies.entrySet().iterator();
while ( it.hasNext() )
for( Entry<String, ? extends DownloadPolicy> entry: policies.entrySet() )
{
Map.Entry entry = (Entry) it.next();
String key = (String) entry.getKey();
DownloadPolicy policy = (DownloadPolicy) entry.getValue();
DownloadPolicy policy = entry.getValue();
String defaultSetting = policy.getDefaultOption();
String setting = StringUtils.defaultString( (String) settings.get( key ), defaultSetting );

@@ -693,24 +686,24 @@ public class DefaultRepositoryProxyConnectors

try
{
AuthenticationInfo authInfo = null;
String username = remoteRepository.getUsername();
String password = remoteRepository.getPassword();
if (username != null && password != null)
{
getLogger().info("Using username " + username + " to connect to remote repository "
+ remoteRepository.getUrl());
authInfo = new AuthenticationInfo();
authInfo.setUserName(username);
authInfo.setPassword(password);
}
else
{
getLogger().info("No authentication for remote repository needed");
}
Repository wagonRepository =
new Repository( remoteRepository.getId(), remoteRepository.getUrl().toString() );
AuthenticationInfo authInfo = null;
String username = remoteRepository.getUsername();
String password = remoteRepository.getPassword();
if ( username != null && password != null )
{
getLogger().info(
"Using username " + username + " to connect to remote repository "
+ remoteRepository.getUrl() );
authInfo = new AuthenticationInfo();
authInfo.setUserName( username );
authInfo.setPassword( password );
}
else
{
getLogger().info( "No authentication for remote repository needed" );
}
Repository wagonRepository = new Repository( remoteRepository.getId(), remoteRepository.getUrl().toString() );
if ( networkProxy != null )
{
wagon.connect( wagonRepository, authInfo, networkProxy );
@@ -742,17 +735,15 @@ public class DefaultRepositoryProxyConnectors
* @param patterns the list of patterns to check.
* @return true if the path matches at least 1 pattern in the provided patterns list.
*/
private boolean matchesPattern( String path, List patterns )
private boolean matchesPattern( String path, List<String> patterns )
{
if ( isEmpty( patterns ) )
if ( CollectionUtils.isEmpty( patterns ) )
{
return false;
}

Iterator it = patterns.iterator();
while ( it.hasNext() )
for( String pattern: patterns )
{
String pattern = (String) it.next();
if ( SelectorUtils.matchPath( pattern, path, false ) )
{
return true;
@@ -765,11 +756,11 @@ public class DefaultRepositoryProxyConnectors
/**
* TODO: Ensure that list is correctly ordered based on configuration. See MRM-477
*/
public List getProxyConnectors( ArchivaRepository repository )
public List<ProxyConnector> getProxyConnectors( ArchivaRepository repository )
{
synchronized ( this.proxyConnectorMap )
{
List ret = (List) this.proxyConnectorMap.get( repository.getId() );
List<ProxyConnector> ret = (List<ProxyConnector>) this.proxyConnectorMap.get( repository.getId() );
if ( ret == null )
{
return Collections.EMPTY_LIST;
@@ -780,10 +771,10 @@ public class DefaultRepositoryProxyConnectors

public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
{
if ( ConfigurationNames.isNetworkProxy( propertyName ) ||
ConfigurationNames.isManagedRepositories( propertyName ) ||
ConfigurationNames.isRemoteRepositories( propertyName ) ||
ConfigurationNames.isProxyConnector( propertyName ) )
if ( ConfigurationNames.isNetworkProxy( propertyName )
|| ConfigurationNames.isManagedRepositories( propertyName )
|| ConfigurationNames.isRemoteRepositories( propertyName )
|| ConfigurationNames.isProxyConnector( propertyName ) )
{
initConnectorsAndNetworkProxies();
}
@@ -796,17 +787,14 @@ public class DefaultRepositoryProxyConnectors

private void initConnectorsAndNetworkProxies()
{
Iterator it;

synchronized ( this.proxyConnectorMap )
{
ProxyConnectorOrderComparator proxyOrderSorter = new ProxyConnectorOrderComparator();
this.proxyConnectorMap.clear();

List proxyConfigs = archivaConfiguration.getConfiguration().getProxyConnectors();
it = proxyConfigs.iterator();
while ( it.hasNext() )
List<ProxyConnectorConfiguration> proxyConfigs = archivaConfiguration.getConfiguration().getProxyConnectors();
for( ProxyConnectorConfiguration proxyConfig: proxyConfigs )
{
ProxyConnectorConfiguration proxyConfig = (ProxyConnectorConfiguration) it.next();
String key = proxyConfig.getSourceRepoId();

// Create connector object.
@@ -815,48 +803,52 @@ public class DefaultRepositoryProxyConnectors
connector.setTargetRepository( getRemoteRepository( proxyConfig.getTargetRepoId() ) );
connector.setProxyId( proxyConfig.getProxyId() );
connector.setPolicies( proxyConfig.getPolicies() );
connector.setOrder( proxyConfig.getOrder() );

// Copy any blacklist patterns.
List blacklist = new ArrayList();
if ( !isEmpty( proxyConfig.getBlackListPatterns() ) )
List<String> blacklist = new ArrayList<String>();
if ( CollectionUtils.isNotEmpty( proxyConfig.getBlackListPatterns() ) )
{
blacklist.addAll( proxyConfig.getBlackListPatterns() );
}
connector.setBlacklist( blacklist );

// Copy any whitelist patterns.
List whitelist = new ArrayList();
if ( !isEmpty( proxyConfig.getWhiteListPatterns() ) )
List<String> whitelist = new ArrayList<String>();
if ( CollectionUtils.isNotEmpty( proxyConfig.getWhiteListPatterns() ) )
{
whitelist.addAll( proxyConfig.getWhiteListPatterns() );
}
connector.setWhitelist( whitelist );

// Get other connectors
List connectors = (List) this.proxyConnectorMap.get( key );
List<ProxyConnector> connectors = this.proxyConnectorMap.get( key );
if ( connectors == null )
{
// Create if we are the first.
connectors = new ArrayList();
connectors = new ArrayList<ProxyConnector>();
}

// Add the connector.
connectors.add( connector );
// Ensure the list is sorted.
Collections.sort( connectors, proxyOrderSorter );

// Set the key to the list of connectors.
this.proxyConnectorMap.put( key, connectors );
}
}

synchronized ( this.networkProxyMap )
{
this.networkProxyMap.clear();

List networkProxies = archivaConfiguration.getConfiguration().getNetworkProxies();
it = networkProxies.iterator();
while ( it.hasNext() )
List<NetworkProxyConfiguration> networkProxies = archivaConfiguration.getConfiguration().getNetworkProxies();
for( NetworkProxyConfiguration networkProxyConfig: networkProxies )
{
NetworkProxyConfiguration networkProxyConfig = (NetworkProxyConfiguration) it.next();
String key = networkProxyConfig.getId();

ProxyInfo proxy = new ProxyInfo();
@@ -872,32 +864,22 @@ public class DefaultRepositoryProxyConnectors
}
}

private boolean isEmpty( Collection collection )
{
if ( collection == null )
{
return true;
}

return collection.size() == 0;
}

private ArchivaRepository getRemoteRepository( String repoId )
{
RemoteRepositoryConfiguration repoConfig =
archivaConfiguration.getConfiguration().findRemoteRepositoryById( repoId );
RemoteRepositoryConfiguration repoConfig = archivaConfiguration.getConfiguration()
.findRemoteRepositoryById( repoId );

ArchivaRepository repo = new ArchivaRepository( repoConfig.getId(), repoConfig.getName(), repoConfig.getUrl() );
repo.getModel().setLayoutName( repoConfig.getLayout() );
repo.setUsername(repoConfig.getUsername());
repo.setPassword(repoConfig.getPassword());
repo.setUsername( repoConfig.getUsername() );
repo.setPassword( repoConfig.getPassword() );
return repo;
}

private ArchivaRepository getManagedRepository( String repoId )
{
ManagedRepositoryConfiguration repoConfig =
archivaConfiguration.getConfiguration().findManagedRepositoryById( repoId );
ManagedRepositoryConfiguration repoConfig = archivaConfiguration.getConfiguration()
.findManagedRepositoryById( repoId );

return ArchivaConfigurationAdaptor.toArchivaRepository( repoConfig );
}

+ 23
- 11
archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/ProxyConnector.java View File

@@ -39,20 +39,22 @@ public class ProxyConnector

private ArchivaRepository targetRepository;

private List blacklist;
private List<String> blacklist;

private List whitelist;
private List<String> whitelist;

private String proxyId;
private int order;

private Map policies;
private Map<String, String> policies;

public List getBlacklist()
public List<String> getBlacklist()
{
return blacklist;
}

public void setBlacklist( List blacklist )
public void setBlacklist( List<String> blacklist )
{
this.blacklist = blacklist;
}
@@ -77,22 +79,22 @@ public class ProxyConnector
this.targetRepository = targetRepository;
}

public List getWhitelist()
public List<String> getWhitelist()
{
return whitelist;
}

public void setWhitelist( List whitelist )
public void setWhitelist( List<String> whitelist )
{
this.whitelist = whitelist;
}

public Map getPolicies()
public Map<String, String> getPolicies()
{
return policies;
}

public void setPolicies( Map policies )
public void setPolicies( Map<String, String> policies )
{
this.policies = policies;
}
@@ -116,10 +118,10 @@ public class ProxyConnector
sb.append( " target:" ).append( this.targetRepository ).append( "\n" );
sb.append( " proxyId:" ).append( this.proxyId ).append( "\n" );

Iterator keys = this.policies.keySet().iterator();
Iterator<String> keys = this.policies.keySet().iterator();
while ( keys.hasNext() )
{
String name = (String) keys.next();
String name = keys.next();
sb.append( " policy[" ).append( name ).append( "]:" );
sb.append( this.policies.get( name ) ).append( "\n" );
}
@@ -133,4 +135,14 @@ public class ProxyConnector
{
this.policies.put( policyId, policySetting );
}

public int getOrder()
{
return order;
}

public void setOrder( int order )
{
this.order = order;
}
}

+ 71
- 0
archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/ProxyConnectorOrderComparator.java View File

@@ -0,0 +1,71 @@
package org.apache.maven.archiva.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import java.util.Comparator;

/**
* ProxyConnectorOrderComparator
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ProxyConnectorOrderComparator
implements Comparator<ProxyConnector>
{
private static ProxyConnectorOrderComparator INSTANCE = new ProxyConnectorOrderComparator();

public static ProxyConnectorOrderComparator getInstance()
{
return INSTANCE;
}

public int compare( ProxyConnector o1, ProxyConnector o2 )
{
if ( o1 == null && o2 == null )
{
return 0;
}

// Ensure null goes to end of list.
if ( o1 == null && o2 != null )
{
return 1;
}

if ( o1 != null && o2 == null )
{
return -1;
}

// Ensure 0 (unordered) goes to end of list.
if ( o1.getOrder() == 0 && o2.getOrder() != 0 )
{
return 1;
}

if ( o1.getOrder() != 0 && o2.getOrder() == 0 )
{
return -1;
}

return o1.getOrder() - o2.getOrder();
}
}

+ 1
- 1
archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/RepositoryProxyConnectors.java View File

@@ -86,7 +86,7 @@ public interface RepositoryProxyConnectors
* @param repository the source repository to look for.
* @return the List of {@link ProxyConnector} objects.
*/
public List getProxyConnectors( ArchivaRepository repository );
public List<ProxyConnector> getProxyConnectors( ArchivaRepository repository );

/**
* Tests to see if the provided repository is a source repository for

+ 2
- 5
archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/AbstractProxyTestCase.java View File

@@ -44,7 +44,6 @@ import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;

/**
@@ -162,15 +161,13 @@ public abstract class AbstractProxyTestCase
return;
}

Collection tmpFiles = FileUtils.listFiles( workingDir, new String[]{"tmp"}, false );
Collection<File> tmpFiles = FileUtils.listFiles( workingDir, new String[]{"tmp"}, false );
if ( !tmpFiles.isEmpty() )
{
StringBuffer emsg = new StringBuffer();
emsg.append( "Found Temp Files in dir: " ).append( workingDir.getPath() );
Iterator it = tmpFiles.iterator();
while ( it.hasNext() )
for( File tfile: tmpFiles )
{
File tfile = (File) it.next();
emsg.append( "\n " ).append( tfile.getName() );
}
fail( emsg.toString() );

+ 2
- 5
archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/MockConfiguration.java View File

@@ -27,7 +27,6 @@ import org.codehaus.plexus.registry.RegistryListener;
import org.easymock.MockControl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
@@ -44,7 +43,7 @@ public class MockConfiguration
{
private Configuration configuration = new Configuration();

private List listeners = new ArrayList();
private List<RegistryListener> listeners = new ArrayList<RegistryListener>();

private MockControl registryControl;

@@ -74,10 +73,8 @@ public class MockConfiguration

public void triggerChange( String name, String value )
{
Iterator it = listeners.iterator();
while ( it.hasNext() )
for( RegistryListener listener: listeners )
{
RegistryListener listener = (RegistryListener) it.next();
try
{
listener.afterConfigurationChange( registryMock, name, value );

+ 1
- 1
archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/WagonDelegate.java View File

@@ -86,7 +86,7 @@ public class WagonDelegate
return delegate.resourceExists( resourceName );
}

public List getFileList( String destinationDirectory )
public List<String> getFileList( String destinationDirectory )
throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
{
return delegate.getFileList( destinationDirectory );

+ 4
- 0
archiva-web/archiva-webapp/pom.xml View File

@@ -316,6 +316,10 @@
</connector>
</connectors>
<systemProperties>
<systemProperty>
<name>plexus.home</name>
<value>${project.build.directory}/appserver-base</value>
</systemProperty>
<systemProperty>
<name>appserver.base</name>
<value>${project.build.directory}/appserver-base</value>

+ 1
- 1
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/appearance/AbstractAppearanceAction.java View File

@@ -40,7 +40,7 @@ public abstract class AbstractAppearanceAction
/**
* @plexus.requirement role="org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout"
*/
private Map repositoryLayouts;
private Map<String, ArtifactRepositoryLayout> repositoryLayouts;

/**
* @plexus.requirement

+ 137
- 0
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/AbstractProxyConnectorAction.java View File

@@ -0,0 +1,137 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.functors.NotPredicate;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.IndeterminateConfigurationException;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.configuration.functors.ProxyConnectorSelectionPredicate;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
import org.codehaus.plexus.redback.rbac.Resource;
import org.codehaus.plexus.redback.xwork.interceptor.SecureAction;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionException;
import org.codehaus.plexus.registry.RegistryException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;

import java.util.List;
import java.util.Map;

/**
* AbstractProxyConnectorAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public abstract class AbstractProxyConnectorAction
extends PlexusActionSupport
implements SecureAction
{
public static final String DIRECT_CONNECTION = "(direct connection)";

/**
* @plexus.requirement
*/
protected ArchivaConfiguration archivaConfiguration;

public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
SecureActionBundle bundle = new SecureActionBundle();

bundle.setRequiresAuthentication( true );
bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );

return bundle;
}

public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration )
{
this.archivaConfiguration = archivaConfiguration;
}

protected void addProxyConnector( ProxyConnectorConfiguration proxyConnector )
{
getConfig().addProxyConnector( proxyConnector );
}

protected ProxyConnectorConfiguration findProxyConnector( String sourceId, String targetId )
{
if ( StringUtils.isBlank( sourceId ) )
{
return null;
}

if ( StringUtils.isBlank( targetId ) )
{
return null;
}

ProxyConnectorSelectionPredicate selectedProxy = new ProxyConnectorSelectionPredicate( sourceId, targetId );
return (ProxyConnectorConfiguration) CollectionUtils.find( getConfig().getProxyConnectors(), selectedProxy );
}

protected Configuration getConfig()
{
return this.archivaConfiguration.getConfiguration();
}

protected Map<String, List<ProxyConnectorConfiguration>> createProxyConnectorMap()
{
return getConfig().getProxyConnectorAsMap();
}

protected void removeConnector( String sourceId, String targetId )
{
ProxyConnectorSelectionPredicate selectedProxy = new ProxyConnectorSelectionPredicate( sourceId, targetId );
NotPredicate notSelectedProxy = new NotPredicate( selectedProxy );
CollectionUtils.filter( getConfig().getProxyConnectors(), notSelectedProxy );
}

protected void removeProxyConnector( ProxyConnectorConfiguration connector )
{
getConfig().removeProxyConnector( connector );
}

protected String saveConfiguration()
{
try
{
archivaConfiguration.save( getConfig() );
addActionMessage( "Successfully saved configuration" );
}
catch ( RegistryException e )
{
addActionError( "Unable to save configuration: " + e.getMessage() );
return INPUT;
}
catch ( IndeterminateConfigurationException e )
{
addActionError( e.getMessage() );
return INPUT;
}

return SUCCESS;
}
}

+ 432
- 0
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/AbstractProxyConnectorFormAction.java View File

@@ -0,0 +1,432 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import com.opensymphony.xwork.Preparable;

import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.policies.DownloadPolicy;
import org.apache.maven.archiva.policies.PostDownloadPolicy;
import org.apache.maven.archiva.policies.PreDownloadPolicy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* AbstractProxyConnectorFormAction - generic fields and methods for either add or edit actions related with the
* Proxy Connector.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public abstract class AbstractProxyConnectorFormAction
extends AbstractProxyConnectorAction
implements Preparable
{

/**
* @plexus.requirement role="org.apache.maven.archiva.policies.PreDownloadPolicy"
*/
private Map<String, PreDownloadPolicy> preDownloadPolicyMap;

/**
* @plexus.requirement role="org.apache.maven.archiva.policies.PostDownloadPolicy"
*/
private Map<String, PostDownloadPolicy> postDownloadPolicyMap;

/**
* The list of network proxy ids that are available.
*/
private List<String> proxyIdOptions;

/**
* The list of managed repository ids that are available.
*/
private List<String> managedRepoIdList;

/**
* The list of remove repository ids that are available.
*/
private List<String> remoteRepoIdList;

/**
* The map of policies that are available to be set.
*/
private Map<String, DownloadPolicy> policyMap;

/**
* The property key to add or remove.
*/
private String propertyKey;

/**
* The property value to add.
*/
private String propertyValue;

/**
* The blacklist pattern to add.
*/
private String blackListPattern;

/**
* The whitelist pattern to add.
*/
private String whiteListPattern;

/**
* The pattern to add or remove (black or white).
*/
private String pattern;

/**
* The model for this action.
*/
protected ProxyConnectorConfiguration connector;

public String addBlackListPattern()
{
String pattern = getBlackListPattern();

if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot add a blank black list pattern." );
}

if ( !hasActionErrors() )
{
getConnector().getBlackListPatterns().add( pattern );
setBlackListPattern( null );
}

return INPUT;
}

public String addProperty()
{
String key = getPropertyKey();
String value = getPropertyValue();

if ( StringUtils.isBlank( key ) )
{
addActionError( "Unable to add property with blank key." );
}

if ( StringUtils.isBlank( value ) )
{
addActionError( "Unable to add property with blank value." );
}

if ( !hasActionErrors() )
{
getConnector().getProperties().put( key, value );
setPropertyKey( null );
setPropertyValue( null );
}

return INPUT;
}

public String addWhiteListPattern()
{
String pattern = getWhiteListPattern();

if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot add a blank white list pattern." );
}

if ( !hasActionErrors() )
{
getConnector().getWhiteListPatterns().add( pattern );
setWhiteListPattern( null );
}

return INPUT;
}

public String getBlackListPattern()
{
return blackListPattern;
}

public ProxyConnectorConfiguration getConnector()
{
return connector;
}

public List<String> getManagedRepoIdList()
{
return managedRepoIdList;
}

public String getPattern()
{
return pattern;
}

public Map<String, DownloadPolicy> getPolicyMap()
{
return policyMap;
}

public String getPropertyKey()
{
return propertyKey;
}

public String getPropertyValue()
{
return propertyValue;
}

public List<String> getProxyIdOptions()
{
return proxyIdOptions;
}

public List<String> getRemoteRepoIdList()
{
return remoteRepoIdList;
}

public String getWhiteListPattern()
{
return whiteListPattern;
}

public void prepare()
{
proxyIdOptions = createNetworkProxyOptions();
managedRepoIdList = createManagedRepoOptions();
remoteRepoIdList = createRemoteRepoOptions();
policyMap = createPolicyMap();
}

public String removeBlackListPattern()
{
String pattern = getPattern();

if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot remove a blank black list pattern." );
}

if ( !getConnector().getBlackListPatterns().contains( pattern ) )
{
addActionError( "Non-existant black list pattern [" + pattern + "], no black list pattern removed." );
}

if ( !hasActionErrors() )
{
getConnector().getBlackListPatterns().remove( pattern );
}

setBlackListPattern( null );
setPattern( null );

return INPUT;
}

public String removeProperty()
{
String key = getPropertyKey();

if ( StringUtils.isBlank( key ) )
{
addActionError( "Unable to remove property with blank key." );
}

if ( !getConnector().getProperties().containsKey( key ) )
{
addActionError( "Non-existant property key [" + pattern + "], no property was removed." );
}

if ( !hasActionErrors() )
{
getConnector().getProperties().remove( key );
}

setPropertyKey( null );
setPropertyValue( null );

return INPUT;
}

public String removeWhiteListPattern()
{
String pattern = getPattern();

if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot remove a blank white list pattern." );
}

if ( !getConnector().getWhiteListPatterns().contains( pattern ) )
{
addActionError( "Non-existant white list pattern [" + pattern + "], no white list pattern removed." );
}

if ( !hasActionErrors() )
{
getConnector().getWhiteListPatterns().remove( pattern );
}

setWhiteListPattern( null );
setPattern( null );

return INPUT;
}

public void setBlackListPattern( String blackListPattern )
{
this.blackListPattern = blackListPattern;
}

public void setConnector( ProxyConnectorConfiguration connector )
{
this.connector = connector;
}

public void setManagedRepoIdList( List<String> managedRepoIdList )
{
this.managedRepoIdList = managedRepoIdList;
}

public void setPattern( String pattern )
{
this.pattern = pattern;
}

public void setPolicyMap( Map<String, DownloadPolicy> policyMap )
{
this.policyMap = policyMap;
}

public void setPropertyKey( String propertyKey )
{
this.propertyKey = propertyKey;
}

public void setPropertyValue( String propertyValue )
{
this.propertyValue = propertyValue;
}

public void setProxyIdOptions( List<String> proxyIdOptions )
{
this.proxyIdOptions = proxyIdOptions;
}

public void setRemoteRepoIdList( List<String> remoteRepoIdList )
{
this.remoteRepoIdList = remoteRepoIdList;
}

public void setWhiteListPattern( String whiteListPattern )
{
this.whiteListPattern = whiteListPattern;
}

protected List<String> createManagedRepoOptions()
{
return new ArrayList<String>( getConfig().getManagedRepositoriesAsMap().keySet() );
}

protected List<String> createNetworkProxyOptions()
{
List<String> options = new ArrayList<String>();

options.add( DIRECT_CONNECTION );
options.addAll( getConfig().getNetworkProxiesAsMap().keySet() );

return options;
}

protected Map<String, DownloadPolicy> createPolicyMap()
{
Map<String, DownloadPolicy> policyMap = new HashMap<String, DownloadPolicy>();

policyMap.putAll( preDownloadPolicyMap );
policyMap.putAll( postDownloadPolicyMap );

return policyMap;
}

protected List<String> createRemoteRepoOptions()
{
return new ArrayList<String>( getConfig().getRemoteRepositoriesAsMap().keySet() );
}

protected void validateConnector()
{
if ( connector.getPolicies() == null )
{
addActionError( "Policies must be set." );
}
else
{
// Validate / Fix policy settings arriving from browser.
for ( Map.Entry<String, DownloadPolicy> entry : getPolicyMap().entrySet() )
{
String policyId = (String) entry.getKey();
DownloadPolicy policy = (DownloadPolicy) entry.getValue();
List<String> options = policy.getOptions();

if ( !connector.getPolicies().containsKey( policyId ) )
{
addActionError( "Policy [" + policyId + "] must be set (missing id)." );
continue;
}

// Ugly hack to compensate for ugly browsers.
Object o = connector.getPolicies().get( policyId );
String value;
if ( o.getClass().isArray() )
{
String arr[] = (String[]) o;
value = arr[0];
}
else
{
value = (String) o;
}

connector.getPolicies().put( policyId, value );

if ( StringUtils.isBlank( value ) )
{
addActionError( "Policy [" + policyId + "] must be set (missing value)." );
continue;
}

if ( !options.contains( value ) )
{
addActionError( "Value of [" + value + "] is invalid for policy [" + policyId + "], valid values: "
+ options );
continue;
}
}
}
}
}

+ 81
- 0
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/AddProxyConnectorAction.java View File

@@ -0,0 +1,81 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;

/**
* AddProxyConnectorAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="addProxyConnectorAction"
*/
public class AddProxyConnectorAction
extends AbstractProxyConnectorFormAction
{
@Override
public void prepare()
{
super.prepare();
connector = new ProxyConnectorConfiguration();
}
public String input()
{
return INPUT;
}

public String commit()
{
/* Too complex for webwork's ${Action}-validation.xml techniques.
* Not appropriate for use with webwork's implements Validatable, as that validates regardless of
* the request method, such as .addProperty() or .addWhiteList().
*
* This validation is ultimately only useful on this one request method.
*/
String sourceId = connector.getSourceRepoId();
String targetId = connector.getTargetRepoId();

ProxyConnectorConfiguration otherConnector = findProxyConnector( sourceId, targetId );
if ( otherConnector != null )
{
addActionError( "Unable to add proxy connector, as one already exists with source repository id ["
+ sourceId + "] and target repository id [" + targetId + "]." );
}
validateConnector();

if ( hasActionErrors() )
{
return INPUT;
}
if( StringUtils.equals( DIRECT_CONNECTION, connector.getProxyId() ) )
{
connector.setProxyId( null );
}

addProxyConnector( connector );
return saveConfiguration();
}
}

+ 0
- 576
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/ConfigureProxyConnectorAction.java View File

@@ -1,576 +0,0 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import com.opensymphony.xwork.Preparable;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.functors.NotPredicate;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.IndeterminateConfigurationException;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.configuration.functors.ProxyConnectorSelectionPredicate;
import org.apache.maven.archiva.policies.DownloadPolicy;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.codehaus.plexus.redback.rbac.Resource;
import org.codehaus.plexus.redback.xwork.interceptor.SecureAction;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionException;
import org.codehaus.plexus.registry.RegistryException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
* ConfigureProxyConnectorAction
*
* @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
* @version $Id$
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureProxyConnectorAction"
*/
public class ConfigureProxyConnectorAction
extends PlexusActionSupport
implements SecureAction, Preparable, Initializable
{
private static final String DIRECT_CONNECTION = "(direct connection)";

/**
* @plexus.requirement
*/
private ArchivaConfiguration archivaConfiguration;

/**
* @plexus.requirement role="org.apache.maven.archiva.policies.PreDownloadPolicy"
*/
private Map preDownloadPolicyMap;

/**
* @plexus.requirement role="org.apache.maven.archiva.policies.PostDownloadPolicy"
*/
private Map postDownloadPolicyMap;

/**
* The model for this action.
*/
private ProxyConnectorConfiguration connector;

private Map policyMap;

private String source;

private String target;

private String mode;

private String propertyKey;

private String propertyValue;

private String pattern;

/**
* The list of possible proxy ids.
*/
private List proxyIdOptions = new ArrayList();

/**
* The list of local repository ids.
*/
private List managedRepoIdList = new ArrayList();

/**
* The list of remote repository ids.
*/
private List remoteRepoIdList = new ArrayList();

/**
* The blacklist pattern to add.
*/
private String blackListPattern;

/**
* The whitelist pattern to add.
*/
private String whiteListPattern;

public String add()
{
this.mode = "add";
return INPUT;
}

public String confirm()
{
return INPUT;
}

public String delete()
{
Configuration config = archivaConfiguration.getConfiguration();

String source = getSource();
if ( StringUtils.isBlank( source ) )
{
addActionError( "Unable to delete proxy connector with blank id for its source." );
return SUCCESS;
}

String target = getTarget();
if ( StringUtils.isBlank( target ) )
{
addActionError( "Unable to delete proxy connector with blank id for its target." );
return SUCCESS;
}

ProxyConnectorSelectionPredicate proxyConnectorSelection =
new ProxyConnectorSelectionPredicate( source, target );
ProxyConnectorConfiguration proxyConnectorConfiguration =
(ProxyConnectorConfiguration) CollectionUtils.find( config
.getProxyConnectors(), proxyConnectorSelection );
if ( proxyConnectorConfiguration == null )
{
addActionError( "Unable to remove proxy connector, proxy connector with source [" + source +
"] and target [" + target + "] not found." );
return SUCCESS;
}

archivaConfiguration.getConfiguration().removeProxyConnector( proxyConnectorConfiguration );
addActionMessage( "Successfully removed proxy connector [" + source + " , " + target + " ]" );
return saveConfiguration();
}

public String addProperty()
{
String key = getPropertyKey();
String value = getPropertyValue();

if ( StringUtils.isBlank( key ) )
{
addActionError( "Unable to add property with blank key." );
}

if ( StringUtils.isBlank( value ) )
{
addActionError( "Unable to add property with blank value." );
}

if ( !hasActionErrors() )
{
getConnector().getProperties().put( key, value );
setPropertyKey( null );
setPropertyValue( null );
}

return INPUT;
}

public String removeProperty()
{
String key = getPropertyKey();

if ( StringUtils.isBlank( key ) )
{
addActionError( "Unable to remove property with blank key." );
}

if ( !hasActionErrors() )
{
getConnector().getProperties().remove( key );
setPropertyKey( null );
setPropertyValue( null );
}

return INPUT;
}

public String addWhiteListPattern()
{
String pattern = getWhiteListPattern();

if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot add a blank white list pattern." );
}

if ( !hasActionErrors() )
{
getConnector().getWhiteListPatterns().add( pattern );
setWhiteListPattern( null );
}

return INPUT;
}

public String removeWhiteListPattern()
{
String pattern = getPattern();

if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot remove a blank white list pattern." );
}

if ( !hasActionErrors() )
{
getConnector().getWhiteListPatterns().remove( pattern );
setWhiteListPattern( null );
}

return INPUT;
}

public String addBlackListPattern()
{
String pattern = getBlackListPattern();

if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot add a blank black list pattern." );
}

if ( !hasActionErrors() )
{
getConnector().getBlackListPatterns().add( pattern );
setBlackListPattern( null );
}

return INPUT;
}

public String removeBlackListPattern()
{
String pattern = getPattern();

if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot remove a blank black list pattern." );
}

if ( !hasActionErrors() )
{
getConnector().getBlackListPatterns().remove( pattern );
setBlackListPattern( null );
}

return INPUT;
}

public String edit()
{
this.mode = "edit";
return INPUT;
}

public String getBlackListPattern()
{
return blackListPattern;
}

public ProxyConnectorConfiguration getConnector()
{
return connector;
}

public List getManagedRepoIdList()
{
return managedRepoIdList;
}

public String getMode()
{
return this.mode;
}

public Map getPolicyMap()
{
return policyMap;
}

public String getPropertyKey()
{
return propertyKey;
}

public String getPropertyValue()
{
return propertyValue;
}

public List getProxyIdOptions()
{
return proxyIdOptions;
}

public List getRemoteRepoIdList()
{
return remoteRepoIdList;
}

public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
SecureActionBundle bundle = new SecureActionBundle();

bundle.setRequiresAuthentication( true );
bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );

return bundle;
}

public String getSource()
{
return source;
}

public String getTarget()
{
return target;
}

public String getWhiteListPattern()
{
return whiteListPattern;
}

public void initialize()
throws InitializationException
{
policyMap = new HashMap();
policyMap.putAll( preDownloadPolicyMap );
policyMap.putAll( postDownloadPolicyMap );
}

public String input()
{
return INPUT;
}

public void prepare()
throws Exception
{
String sourceId = getSource();
String targetId = getTarget();

if ( StringUtils.isBlank( sourceId ) || StringUtils.isBlank( targetId ) )
{
if ( this.connector == null )
{
this.connector = new ProxyConnectorConfiguration();
}
}
else
{
this.connector = findProxyConnector( sourceId, targetId );
}

Configuration config = archivaConfiguration.getConfiguration();

// Gather Network Proxy Ids.
this.proxyIdOptions = new ArrayList();
this.proxyIdOptions.add( DIRECT_CONNECTION );
this.proxyIdOptions.addAll( config.getNetworkProxiesAsMap().keySet() );

// Gather Local & Remote Repo Ids.
this.remoteRepoIdList = new ArrayList( config.getRemoteRepositoriesAsMap().keySet() );
this.managedRepoIdList = new ArrayList( config.getManagedRepositoriesAsMap().keySet() );
}

public String save()
{
String mode = getMode();

String sourceId = getConnector().getSourceRepoId();
String targetId = getConnector().getTargetRepoId();

if ( !validateConnector( getConnector() ) )
{
return INPUT;
}

if ( StringUtils.equalsIgnoreCase( "edit", mode ) )
{
removeConnector( sourceId, targetId );
}
else
{
if ( findProxyConnector( sourceId, targetId ) != null )
{
addActionError( "Unable to add new proxy connector with source [" + sourceId + "] and target [" +
targetId + "] as previously declared proxy connector, go edit that one instead." );
return INPUT;
}
}

if ( StringUtils.equals( DIRECT_CONNECTION, getConnector().getProxyId() ) )
{
getConnector().setProxyId( null );
}

addProxyConnector( getConnector() );
return saveConfiguration();
}

public void setBlackListPattern( String blackListPattern )
{
this.blackListPattern = blackListPattern;
}

public void setConnector( ProxyConnectorConfiguration connector )
{
this.connector = connector;
}

public void setMode( String mode )
{
this.mode = mode;
}

public void setPropertyKey( String propertyKey )
{
this.propertyKey = propertyKey;
}

public void setPropertyValue( String propertyValue )
{
this.propertyValue = propertyValue;
}

public void setSource( String source )
{
this.source = source;
}

public void setTarget( String target )
{
this.target = target;
}

public void setWhiteListPattern( String whiteListPattern )
{
this.whiteListPattern = whiteListPattern;
}

private void addProxyConnector( ProxyConnectorConfiguration proxyConnector )
{
archivaConfiguration.getConfiguration().addProxyConnector( proxyConnector );
}

private ProxyConnectorConfiguration findProxyConnector( String sourceId, String targetId )
{
Configuration config = archivaConfiguration.getConfiguration();

ProxyConnectorSelectionPredicate selectedProxy = new ProxyConnectorSelectionPredicate( sourceId, targetId );
return (ProxyConnectorConfiguration) CollectionUtils.find( config.getProxyConnectors(), selectedProxy );
}

public boolean validateConnector( ProxyConnectorConfiguration proxyConnector )
{
if ( proxyConnector.getPolicies() == null )
{
addActionError( "Policies must be set." );
}

Iterator it = policyMap.entrySet().iterator();
while ( it.hasNext() )
{
Map.Entry entry = (Entry) it.next();
String policyId = (String) entry.getKey();
DownloadPolicy policy = (DownloadPolicy) entry.getValue();
List options = policy.getOptions();

if ( !proxyConnector.getPolicies().containsKey( policyId ) )
{
addActionError( "Policy [" + policyId + "] must be set (missing id)." );
continue;
}

String arr[] = (String[]) proxyConnector.getPolicies().get( policyId );
String value = arr[0];

proxyConnector.getPolicies().put( policyId, value );

if ( StringUtils.isBlank( value ) )
{
addActionError( "Policy [" + policyId + "] must be set (missing value)." );
continue;
}

if ( !options.contains( value ) )
{
addActionError(
"Value of [" + value + "] is invalid for policy [" + policyId + "], valid values: " + options );
continue;
}
}

return !hasActionErrors();
}

private void removeConnector( String sourceId, String targetId )
{
ProxyConnectorSelectionPredicate selectedProxy = new ProxyConnectorSelectionPredicate( sourceId, targetId );
NotPredicate notSelectedProxy = new NotPredicate( selectedProxy );
CollectionUtils.filter( archivaConfiguration.getConfiguration().getProxyConnectors(), notSelectedProxy );
}

private String saveConfiguration()
{
try
{
archivaConfiguration.save( archivaConfiguration.getConfiguration() );
addActionMessage( "Successfully saved configuration" );
}
catch ( RegistryException e )
{
addActionError( "Unable to save configuration: " + e.getMessage() );
return INPUT;
}
catch ( IndeterminateConfigurationException e )
{
addActionError( e.getMessage() );
return INPUT;
}

return SUCCESS;
}

public String getPattern()
{
return pattern;
}

public void setPattern( String pattern )
{
this.pattern = pattern;
}

public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration )
{
this.archivaConfiguration = archivaConfiguration;
}
}

+ 106
- 0
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/DeleteProxyConnectorAction.java View File

@@ -0,0 +1,106 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;

/**
* DeleteProxyConnectorAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="deleteProxyConnectorAction"
*/
public class DeleteProxyConnectorAction
extends AbstractProxyConnectorAction
{
private String sourceId;

private String targetId;

private ProxyConnectorConfiguration proxyConfig;

public String confirmDelete()
{
this.proxyConfig = findProxyConnector( sourceId, targetId );

// Not set? Then there is nothing to delete.
if ( this.proxyConfig == null )
{
addActionError( "Unable to delete proxy configuration, configuration with source [" + sourceId
+ "], and target [" + targetId + "] does not exist." );
return ERROR;
}

return INPUT;
}

public String delete()
{
this.proxyConfig = findProxyConnector( sourceId, targetId );

// Not set? Then there is nothing to delete.
if ( this.proxyConfig == null )
{
addActionError( "Unable to delete proxy configuration, configuration with source [" + sourceId
+ "], and target [" + targetId + "] does not exist." );
return ERROR;
}

if ( hasActionErrors() )
{
return ERROR;
}
removeProxyConnector( proxyConfig );
addActionMessage( "Successfully removed proxy connector [" + sourceId + " , " + targetId + " ]" );

setSourceId( null );
setTargetId( null );
return saveConfiguration();
}

public String getSourceId()
{
return sourceId;
}

public void setSourceId( String sourceId )
{
this.sourceId = sourceId;
}

public String getTargetId()
{
return targetId;
}

public void setTargetId( String targetId )
{
this.targetId = targetId;
}

public ProxyConnectorConfiguration getProxyConfig()
{
return proxyConfig;
}
}

+ 114
- 0
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/EditProxyConnectorAction.java View File

@@ -0,0 +1,114 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;


/**
* EditProxyConnectorAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="editProxyConnectorAction"
*/
public class EditProxyConnectorAction
extends AbstractProxyConnectorFormAction
{
/**
* The proxy connector source id to edit. (used with {@link #target})
*/
private String source;

/**
* The proxy connector target id to edit. (used with {@link #source})
*/
private String target;

@Override
public void prepare()
{
super.prepare();

connector = findProxyConnector( source, target );
}

public String input()
{
if ( connector == null )
{
addActionError( "Unable to edit non existant proxy connector with source [" + source + "] and target ["
+ target + "]" );
return ERROR;
}

return INPUT;
}

public String commit()
{
validateConnector();

if ( hasActionErrors() )
{
return INPUT;
}

String sourceId = connector.getSourceRepoId();
String targetId = connector.getTargetRepoId();

ProxyConnectorConfiguration otherConnector = findProxyConnector( sourceId, targetId );
if ( otherConnector != null )
{
// Remove the previous connector.
removeProxyConnector( otherConnector );
}

if ( hasActionErrors() )
{
return INPUT;
}

addProxyConnector( connector );
return saveConfiguration();
}

public String getSource()
{
return source;
}

public void setSource( String source )
{
this.source = source;
}

public String getTarget()
{
return target;
}

public void setTarget( String target )
{
this.target = target;
}

}

+ 11
- 57
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/ProxyConnectorsAction.java View File

@@ -20,19 +20,11 @@ package org.apache.maven.archiva.web.action.admin.connectors.proxy;
*/

import com.opensymphony.xwork.Preparable;
import org.apache.commons.collections.Closure;
import org.apache.commons.collections.CollectionUtils;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;

import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
import org.codehaus.plexus.redback.rbac.Resource;
import org.codehaus.plexus.redback.xwork.interceptor.SecureAction;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -42,75 +34,37 @@ import java.util.Map;
*
* @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="proxyConnectorsAction"
*/
public class ProxyConnectorsAction
extends PlexusActionSupport
implements SecureAction, Preparable
extends AbstractProxyConnectorAction
implements Preparable
{
/**
* @plexus.requirement
*/
private ArchivaConfiguration archivaConfiguration;

private Map repoMap;
private Map<String, AbstractRepositoryConfiguration> repoMap;

/**
* Map of Proxy Connectors.
*/
private Map proxyConnectorMap;
private Map<String, List<ProxyConnectorConfiguration>> proxyConnectorMap;

public void prepare()
{
Configuration config = archivaConfiguration.getConfiguration();

repoMap = new HashMap();
repoMap = new HashMap<String, AbstractRepositoryConfiguration>();
repoMap.putAll( config.getRemoteRepositoriesAsMap() );
repoMap.putAll( config.getManagedRepositoriesAsMap() );

proxyConnectorMap = new HashMap();

Closure addToProxyConnectorMap = new Closure()
{
public void execute( Object input )
{
if ( input instanceof ProxyConnectorConfiguration )
{
ProxyConnectorConfiguration proxyConfig = (ProxyConnectorConfiguration) input;
String key = proxyConfig.getSourceRepoId();

List connectors = (List) proxyConnectorMap.get( key );
if ( connectors == null )
{
connectors = new ArrayList();
proxyConnectorMap.put( key, connectors );
}

connectors.add( proxyConfig );
}
}
};

CollectionUtils.forAllDo( config.getProxyConnectors(), addToProxyConnectorMap );
}

public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
SecureActionBundle bundle = new SecureActionBundle();

bundle.setRequiresAuthentication( true );
bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );

return bundle;
proxyConnectorMap = createProxyConnectorMap();
}

public Map getRepoMap()
public Map<String, AbstractRepositoryConfiguration> getRepoMap()
{
return repoMap;
}

public Map getProxyConnectorMap()
public Map<String, List<ProxyConnectorConfiguration>> getProxyConnectorMap()
{
return proxyConnectorMap;
}

+ 0
- 56
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/SingleSelectTransformer.java View File

@@ -1,56 +0,0 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import org.apache.commons.collections.Transformer;

/**
* Ensure that input strings are never arrays.
*
* @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
* @version $Id$
*/
public class SingleSelectTransformer
implements Transformer
{
private static Transformer INSTANCE = new SingleSelectTransformer();

public Object transform( Object input )
{
if ( input instanceof String )
{
if ( input.getClass().isArray() )
{
String arr[] = (String[]) input;
if ( arr.length > 0 )
{
return arr[0];
}
}
}
return null;
}

public static Transformer getInstance()
{
return INSTANCE;
}

}

+ 136
- 0
archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/SortProxyConnectorsAction.java View File

@@ -0,0 +1,136 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;

import java.util.List;

/**
* SortProxyConnectorsAction -
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="sortProxyConnectorsAction"
*/
public class SortProxyConnectorsAction
extends AbstractProxyConnectorAction
{
private String source;

private String target;

public String getSource()
{
return source;
}

public String getTarget()
{
return target;
}

public void setSource( String id )
{
this.source = id;
}

public void setTarget( String id )
{
this.target = id;
}

public String sortDown()
{
List<ProxyConnectorConfiguration> connectors = createProxyConnectorMap().get( source );

int idx = findTargetConnector( connectors, target );

if ( idx >= 0 )
{
incrementConnectorOrder( connectors, idx );
decrementConnectorOrder( connectors, idx + 1 );
}

return saveConfiguration();
}

public String sortUp()
{
List<ProxyConnectorConfiguration> connectors = createProxyConnectorMap().get( source );

int idx = findTargetConnector( connectors, target );

if ( idx >= 0 )
{
decrementConnectorOrder( connectors, idx );
incrementConnectorOrder( connectors, idx - 1 );
}

return saveConfiguration();
}

private void decrementConnectorOrder( List<ProxyConnectorConfiguration> connectors, int idx )
{
if ( !validIndex( connectors, idx ) )
{
// Do nothing.
return;
}

int order = connectors.get( idx ).getOrder();
connectors.get( idx ).setOrder( Math.max( 1, order - 1 ) );
}

private int findTargetConnector( List<ProxyConnectorConfiguration> connectors, String targetRepoId )
{
int idx = ( -1 );

for ( int i = 0; i < connectors.size(); i++ )
{
if ( StringUtils.equals( targetRepoId, connectors.get( i ).getTargetRepoId() ) )
{
idx = i;
break;
}
}

return idx;
}

private void incrementConnectorOrder( List<ProxyConnectorConfiguration> connectors, int idx )
{
if ( !validIndex( connectors, idx ) )
{
// Do nothing.
return;
}

int order = connectors.get( idx ).getOrder();
connectors.get( idx ).setOrder( order + 1 );
}

private boolean validIndex( List<ProxyConnectorConfiguration> connectors, int idx )
{
return ( idx >= 0 ) && ( idx < connectors.size() );
}
}

+ 8
- 8
archiva-web/archiva-webapp/src/main/resources/xwork.xml View File

@@ -286,31 +286,31 @@
<result name="input">/WEB-INF/jsp/admin/proxyConnectors.jsp</result>
</action>

<action name="addProxyConnector" class="configureProxyConnectorAction" method="add">
<result name="input">/WEB-INF/jsp/admin/editProxyConnector.jsp</result>
<action name="addProxyConnector" class="addProxyConnectorAction" method="input">
<result name="input">/WEB-INF/jsp/admin/addProxyConnector.jsp</result>
<result name="success" type="redirect-action">proxyConnectors</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>

<action name="configureProxyConnector" class="configureProxyConnectorAction" method="input">
<action name="editProxyConnector" class="editProxyConnectorAction" method="input">
<result name="input">/WEB-INF/jsp/admin/editProxyConnector.jsp</result>
<result name="success" type="redirect-action">proxyConnectors</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>

<action name="editProxyConnector" class="configureProxyConnectorAction" method="edit">
<action name="sortUpProxyConnector" class="sortProxyConnectorsAction" method="sortUp">
<result name="input">/WEB-INF/jsp/admin/editProxyConnector.jsp</result>
<result name="success" type="redirect-action">proxyConnectors</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="saveProxyConnector" class="configureProxyConnectorAction" method="save">
<action name="sortDownProxyConnector" class="sortProxyConnectorsAction" method="sortDown">
<result name="input">/WEB-INF/jsp/admin/editProxyConnector.jsp</result>
<result name="success" type="redirect-action">proxyConnectors</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="deleteProxyConnector" class="configureProxyConnectorAction" method="confirm">
<action name="deleteProxyConnector" class="deleteProxyConnectorAction" method="confirm">
<result name="input">/WEB-INF/jsp/admin/deleteProxyConnector.jsp</result>
<result name="success" type="redirect-action">proxyConnectors</result>
<interceptor-ref name="configuredPrepareParamsStack"/>

+ 45
- 0
archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/addProxyConnector.jsp View File

@@ -0,0 +1,45 @@
<%--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
--%>

<%@ taglib prefix="ww" uri="/webwork" %>

<html>
<head>
<title>Admin: Add Proxy Connector</title>
<ww:head/>
</head>

<body>

<h1>Admin: Add Proxy Connector</h1>

<div id="contentArea">

<ww:actionerror/>
<ww:actionmessage/>
<ww:form name="saveProxyConnector" method="post" action="addProxyConnector!commit" namespace="/admin" validate="true">
<%@ include file="/WEB-INF/jsp/admin/include/proxyConnectorForm.jspf" %>
<ww:submit value="Add Proxy Connector"/>
</ww:form>

</div>

</body>
</html>

+ 9
- 249
archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/editProxyConnector.jsp View File

@@ -20,266 +20,26 @@
<%@ taglib prefix="ww" uri="/webwork" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:url var="iconDeleteUrl" value="/images/icons/delete.gif"/>
<c:url var="iconCreateUrl" value="/images/icons/create.png"/>

<c:choose>
<c:when test="${mode == 'edit'}">
<c:set var="addedit" value="Edit"/>
</c:when>
<c:otherwise>
<c:set var="addedit" value="Add"/>
</c:otherwise>
</c:choose>

<html>
<head>
<title>Admin : ${addedit} Proxy Connector</title>
<title>Admin : Edit Proxy Connector</title>
<ww:head/>
</head>

<body>

<h1>Admin : ${addedit} Proxy Connector</h1>
<h1>Admin : Edit Proxy Connector</h1>

<div id="contentArea">

<ww:actionerror/>
<ww:actionmessage/>

<ww:form name="saveProxyConnector" method="post" action="saveProxyConnector" namespace="/admin">
<ww:hidden name="mode"/>

<input type="hidden" name="pattern"/>
<ww:select name="connector.proxyId" list="proxyIdOptions" label="Network Proxy" required="true"/>
<ww:select name="connector.sourceRepoId" list="managedRepoIdList"
label="Managed Repository" required="true"/>
<ww:select name="connector.targetRepoId" list="remoteRepoIdList"
label="Remote Repository" required="true"/>

<tr>
<td valign="top"><label>Policies:</label>
</td>
<td>
<table>
<c:forEach items="${policyMap}" var="policy" varStatus="i">
<tr>
<td>
<ww:label for="policy_${policy.key}" required="true"
theme="simple">${policy.key}:
</ww:label>
</td>
<td>
<ww:select name="connector.policies['${policy.key}']"
list="policyMap['${policy.key}'].options"
value="connector.policies['${policy.key}']"
id="policy_${policy.key}"
theme="simple"
cssStyle="width: 10em"/>
</td>
</tr>
</c:forEach>
</table>
</td>
</tr>

<tr class="seperator">
<td valign="top">
<label for="propertiesEntry">Properties:</label>
</td>
<td>
<ww:textfield name="propertyKey" size="15" id="propertiesEntry" theme="simple"
onkeypress="submitenter(event, 'editProxyConnector!addProperty.action')"/>
:
<ww:textfield name="propertyValue" size="15" id="propertiesValue" theme="simple"
onkeypress="submitenter(event, 'editProxyConnector!addProperty.action')"/>
<ww:submit name="action:editProxyConnector!addProperty" value="Add Property" theme="simple"/>
</td>
</tr>

<tr>
<td>
</td>
<td>
<c:choose>
<c:when test="${empty(connector.properties)}">
<i>No properties have been set.</i>
</c:when>
<c:otherwise>
<ww:url id="removePropertyUrl"
action="editProxyConnector"
method="removeProperty"/>
<table>
<c:forEach items="${connector.properties}" var="property" varStatus="i">
<tr>
<td>
<ww:label for="property_${property.key}"
theme="simple">${property.key}</ww:label>
</td>
<td>
<ww:textfield name="connector.properties['${property.key}']"
size="15"
id="property_${property.key}"
theme="simple"/>
</td>
<td>
<ww:a href="#" title="Remove [${property.key}] Property"
onclick="setAndSubmit('propertyKey', '${property.key}', '%{removePropertyUrl}')"
theme="simple">
<img src="${iconDeleteUrl}"/></ww:a>

</td>
</tr>
</c:forEach>
</table>
</c:otherwise>
</c:choose>
</td>
</tr>

<tr class="seperator">
<td valign="top">
<label for="blackListEntry">Black List:</label>
</td>
<td>
<ww:textfield name="blackListPattern" size="30" id="blackListEntry" theme="simple"
onkeypress="submitenter(event, 'editProxyConnector!addBlackListPattern.action')"/>
<ww:submit name="action:editProxyConnector!addBlackListPattern" value="Add Pattern" theme="simple"/>
</td>
</tr>

<tr>
<td>
</td>
<td>
<ww:url id="removeBlackListPatternUrl"
action="editProxyConnector"
method="removeBlackListPattern"/>
<c:choose>
<c:when test="${empty(connector.blackListPatterns)}">
<i>No black list patterns have been set.</i>
</c:when>
<c:otherwise>
<table>
<c:forEach items="${connector.blackListPatterns}" var="pattern" varStatus="i">
<tr>
<td>
<ww:hidden name="connector.blackListPatterns" value="${pattern}"/>
<code>"${pattern}"</code>
</td>
<td>
<ww:a href="#" title="Remove [${pattern}] Pattern"
onclick="setAndSubmit('pattern', '${pattern}', '%{removeBlackListPatternUrl}')"
theme="simple">
<img src="${iconDeleteUrl}"/></ww:a>
</td>
</tr>
</c:forEach>
</table>
</c:otherwise>
</c:choose>
</td>
</tr>

<tr class="seperator">
<td valign="top">
<label for="whiteListEntry">White List:</label>
</td>
<td>
<ww:textfield name="whiteListPattern" size="30" id="whiteListEntry" theme="simple"
onkeypress="submitenter(event, 'editProxyConnector!addWhiteListPattern.action')"/>
<ww:submit name="action:editProxyConnector!addWhiteListPattern" value="Add Pattern" theme="simple"/>
</td>
</tr>
<tr>
<td>
</td>
<td>
<ww:url id="removeWhiteListPatternUrl"
action="editProxyConnector"
method="removeWhiteListPattern"/>
<c:choose>
<c:when test="${empty(connector.whiteListPatterns)}">
<i>No white list patterns have been set.</i>
</c:when>
<c:otherwise>
<table>
<c:forEach items="${connector.whiteListPatterns}" var="pattern" varStatus="i">
<tr>
<td>
<ww:hidden name="connector.whiteListPatterns" value="${pattern}"/>
<code>"${pattern}"</code>
</td>
<td>
<ww:a href="#" title="Remove [${pattern}] Pattern"
onclick="setAndSubmit('pattern', '${pattern}', '%{removeWhiteListPatternUrl}')"
theme="simple">
<img src="${iconDeleteUrl}"/></ww:a>
</td>
</tr>
</c:forEach>
</table>
</c:otherwise>
</c:choose>
</td>
</tr>


<ww:submit value="Save Proxy Connector"/>
</ww:form>

<script type="text/javascript">
<!--
document.getElementById("saveProxyConnector_proxyId").focus();

function setAndSubmit( id, value, action )
{
var f = document.forms['saveProxyConnector'];

f.action = action;
f.elements[id].value = value;
f.submit();
}

function submitForm( action )
{
var f = document.forms['saveProxyConnector'];

f.action = action;
f.submit();
}

function submitenter( e, action )
{
var keycode;

if ( window.event )
{
keycode = window.event.keyCode;
}
else if ( e )
{
keycode = e.which;
}
else
{
return true;
}

if ( keycode == 13 )
{
submitForm(action);
return false;
}
else
{
return true;
}
}

//-->
</script>
<ww:actionerror/>
<ww:actionmessage/>

<ww:form name="saveProxyConnector" method="post" action="editProxyConnector!commit" namespace="/admin" validate="true">
<%@ include file="/WEB-INF/jsp/admin/include/proxyConnectorForm.jspf" %>
<ww:submit value="Save Proxy Connector"/>
</ww:form>
</div>

</body>

+ 256
- 0
archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/include/proxyConnectorForm.jspf View File

@@ -0,0 +1,256 @@
<%--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
--%>
<%@ taglib prefix="ww" uri="/webwork" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:url var="iconDeleteUrl" value="/images/icons/delete.gif"/>
<c:url var="iconCreateUrl" value="/images/icons/create.png"/>

<%-- This hidden 'pattern' field is used by remove (white|black)list scripts --%>
<ww:hidden name="pattern" />

<ww:hidden name="connector.order" />

<ww:select name="connector.proxyId" list="proxyIdOptions" label="Network Proxy" required="true"/>
<ww:select name="connector.sourceRepoId" list="managedRepoIdList"
label="Managed Repository" required="true"/>
<ww:select name="connector.targetRepoId" list="remoteRepoIdList"
label="Remote Repository" required="true"/>

<tr>
<td valign="top"><label>Policies:</label>
</td>
<td>
<table>
<c:forEach items="${policyMap}" var="policy" varStatus="i">
<tr>
<td>
<ww:label for="policy_${policy.key}" required="true"
theme="simple">${policy.key}:
</ww:label>
</td>
<td>
<ww:select name="connector.policies['${policy.key}']"
list="policyMap['${policy.key}'].options"
value="connector.policies['${policy.key}']"
id="policy_${policy.key}"
theme="simple"
cssStyle="width: 10em"/>
</td>
</tr>
</c:forEach>
</table>
</td>
</tr>

<tr class="seperator">
<td valign="top">
<label for="propertiesEntry">Properties:</label>
</td>
<td>
<ww:textfield name="propertyKey" size="15" id="propertiesEntry" theme="simple"
onkeypress="submitenter(event, 'addProperty')"/>
:
<ww:textfield name="propertyValue" size="15" id="propertiesValue" theme="simple"
onkeypress="submitenter(event, 'addProperty')"/>
<input type="button" onclick="submitForm('addProperty')" value="Add Property" />
</td>
</tr>

<tr>
<td>
</td>
<td>
<c:choose>
<c:when test="${empty(connector.properties)}">
<i>No properties have been set.</i>
</c:when>
<c:otherwise>
<table>
<c:forEach items="${connector.properties}" var="property" varStatus="i">
<tr>
<td>
<ww:label for="property_${property.key}"
theme="simple">${property.key}</ww:label>
</td>
<td>
<ww:textfield name="connector.properties['${property.key}']"
size="15"
id="property_${property.key}"
theme="simple"/>
</td>
<td>
<ww:a href="#" title="Remove [${property.key}] Property"
onclick="setAndSubmit('propertyKey', '${property.key}', 'removeProperty')"
theme="simple">
<img src="${iconDeleteUrl}"/></ww:a>
</td>
</tr>
</c:forEach>
</table>
</c:otherwise>
</c:choose>
</td>
</tr>

<tr class="seperator">
<td valign="top">
<label for="blackListEntry">Black List:</label>
</td>
<td>
<ww:textfield name="blackListPattern" size="30" id="blackListEntry" theme="simple"
onkeypress="submitenter(event, 'addBlackListPattern')"/>
<input type="button" onclick="submitForm('addBlackListPattern')" value="Add Pattern" />
</td>
</tr>

<tr>
<td>
</td>
<td>
<c:choose>
<c:when test="${empty(connector.blackListPatterns)}">
<i>No black list patterns have been set.</i>
</c:when>
<c:otherwise>
<table>
<c:forEach items="${connector.blackListPatterns}" var="pattern" varStatus="i">
<tr>
<td>
<ww:hidden name="connector.blackListPatterns" value="${pattern}"/>
<code>"${pattern}"</code>
</td>
<td>
<a href="#" title="Remove [${pattern}] Pattern"
onclick="setAndSubmit('pattern', '${pattern}', 'removeBlackListPattern')">
<img src="${iconDeleteUrl}"/></a>
</td>
</tr>
</c:forEach>
</table>
</c:otherwise>
</c:choose>
</td>
</tr>

<tr class="seperator">
<td valign="top">
<label for="whiteListEntry">White List:</label>
</td>
<td>
<ww:textfield name="whiteListPattern" size="30" id="whiteListEntry" theme="simple"
onkeypress="submitenter(event, 'addWhiteListPattern')"/>
<input type="button" onclick="submitForm('addWhiteListPattern')" value="Add Pattern" />
</td>
</tr>
<tr>
<td>
</td>
<td>
<c:choose>
<c:when test="${empty(connector.whiteListPatterns)}">
<i>No white list patterns have been set.</i>
</c:when>
<c:otherwise>
<table>
<c:forEach items="${connector.whiteListPatterns}" var="pattern" varStatus="i">
<tr>
<td>
<ww:hidden name="connector.whiteListPatterns" value="${pattern}"/>
<code>"${pattern}"</code>
</td>
<td>
<ww:a href="#" title="Remove [${pattern}] Pattern"
onclick="setAndSubmit('pattern', '${pattern}', 'removeWhiteListPattern')"
theme="simple">
<img src="${iconDeleteUrl}"/></ww:a>
</td>
</tr>
</c:forEach>
</table>
</c:otherwise>
</c:choose>
</td>
</tr>

<script type="text/javascript">
<!--
function adjustActionMethod( action, method )
{
var idx = action.indexOf( "!" );
if( idx == (-1) )
{
// no "name!method.action" defined, split by ".action" instead.
idx = action.indexOf( ".action" );
}
return action.substring( 0, idx ) + "!" + method + ".action";
}
function setAndSubmit( id, value, method )
{
var f = document.forms['saveProxyConnector'];

f.action = adjustActionMethod( f.action, method );
f.elements[id].value = value;
f.submit();
}

function submitForm( method )
{
var f = document.forms['saveProxyConnector'];

var before = f.action;
f.action = adjustActionMethod( f.action, method );
f.submit();
}

function submitenter( e, method )
{
var keycode;


if ( window.event )
{
keycode = window.event.keyCode;
}
else if ( e )
{
keycode = e.which;
}
else
{
return true;
}

if ( keycode == 13 )
{
submitForm( method );
return false;
}
else
{
return true;
}
}
document.forms["saveProxyConnector"]["connector.proxyId"].focus();
//-->
</script>


+ 68
- 37
archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/proxyConnectors.jsp View File

@@ -36,6 +36,8 @@
<c:url var="iconDeleteUrl" value="/images/icons/delete.gif"/>
<c:url var="iconEditUrl" value="/images/icons/edit.png"/>
<c:url var="iconCreateUrl" value="/images/icons/create.png"/>
<c:url var="iconUpUrl" value="/images/icons/up.gif"/>
<c:url var="iconDownUrl" value="/images/icons/down.gif"/>

<div id="contentArea">

@@ -59,26 +61,40 @@
<strong>No Repository Proxy Connectors Defined.</strong>
</c:when>
<c:otherwise>
<table width="100%">
<c:forEach items="${proxyConnectorMap}" var="repository" varStatus="i">

<c:forEach items="${repository.value}" var="connector" varStatus="pc">
<tr class="proxyConnector">
<c:if test="${pc.first}">
<td class="managedRepo" rowspan="${fn:length(repository.value)}">
<div>
<img src="<c:url value="/images/archiva-splat-32.gif"/>"/>
<div class="admin">

<p class="id">${repository.key}</p>
<c:forEach items="${proxyConnectorMap}" var="repository" varStatus="i">

<p class="name">${repoMap[repository.key].name}</p>
</div>
</td>
</c:if>
<td class="connector">
<div class="wrap">
<div class="proxyConfig">
<div class="managedRepo">
<img src="<c:url value="/images/archiva-splat-32.gif"/>"/>
<p class="id">${repository.key}</p>
<p class="name">${repoMap[repository.key].name}</p>
</div>

<c:forEach items="${repository.value}" var="connector" varStatus="pc">
<c:choose>
<c:when test='${(pc.index)%2 eq 0}'>
<c:set var="rowColor" value="dark" scope="page"/>
</c:when>
<c:otherwise>
<c:set var="rowColor" value="lite" scope="page"/>
</c:otherwise>
</c:choose>
<div class="connector ${rowColor}">
<div class="controls">
<redback:ifAnyAuthorized permissions="archiva-manage-configuration">
<ww:url id="sortDownProxyConnectorUrl" action="sortDownProxyConnector">
<ww:param name="target" value="%{'${connector.targetRepoId}'}"/>
<ww:param name="source" value="%{'${connector.sourceRepoId}'}"/>
</ww:url>
<ww:url id="sortUpProxyConnectorUrl" action="sortUpProxyConnector">
<ww:param name="target" value="%{'${connector.targetRepoId}'}"/>
<ww:param name="source" value="%{'${connector.sourceRepoId}'}"/>
</ww:url>
<ww:url id="editProxyConnectorUrl" action="editProxyConnector">
<ww:param name="target" value="%{'${connector.targetRepoId}'}"/>
<ww:param name="source" value="%{'${connector.sourceRepoId}'}"/>
@@ -87,6 +103,13 @@
<ww:param name="source" value="%{'${connector.sourceRepoId}'}"/>
<ww:param name="target" value="%{'${connector.targetRepoId}'}"/>
</ww:url>
<em>${connector.order}</em>
<ww:a href="%{sortUpProxyConnectorUrl}" cssClass="up" title="Move Proxy Connector Up">
<img src="${iconUpUrl}"/>
</ww:a>
<ww:a href="%{sortDownProxyConnectorUrl}" cssClass="down" title="Move Proxy Connector Down">
<img src="${iconDownUrl}"/>
</ww:a>
<ww:a href="%{editProxyConnectorUrl}" cssClass="edit" title="Edit Proxy Connector">
<img src="${iconEditUrl}"/>
</ww:a>
@@ -97,13 +120,22 @@
</div>

<h4>Proxy Connector</h4>
<table>
<div class="remoteRepo">
<img src="<c:url value="/images/archiva-world.png"/>"/>
<p class="id">${connector.targetRepoId}</p>
<p class="name">${repoMap[connector.targetRepoId].name}</p>
<p class="url"><a href="${repoMap[connector.targetRepoId].url}">${repoMap[connector.targetRepoId].url}</a></p>
</div>
<a class="expand" href="#" onclick="Effect.toggle('proxySettings_${connector.sourceRepoId}_${connector.targetRepoId}','slide'); return false;">Expand</a>
<table class="settings" style="display: none;" id="proxySettings_${connector.sourceRepoId}_${connector.targetRepoId}">
<tr>
<th nowrap="nowrap">Network Proxy:</th>
<td>
<c:choose>
<c:when test="${empty(connector.proxyId)}">
<i>(Direct Connection)</i>
<span class="directConnection">(Direct Connection)</span>
</c:when>
<c:otherwise>
<ww:url id="editProxyIdUrl" action="editNetworkProxy">
@@ -120,9 +152,14 @@
<tr>
<th>Policies:</th>
<td nowrap="nowrap">
<c:forEach items="${connector.policies}" var="policies">
<p><em>${policies.key}</em>: ${policies.value}</p>
</c:forEach>
<table class="policies">
<c:forEach items="${connector.policies}" var="policies">
<tr>
<th>${policies.key}</th>
<td>${policies.value}</td>
</tr>
</c:forEach>
</table>
</td>
</tr>

@@ -152,30 +189,24 @@
<tr>
<th>Properties:</th>
<td>
<c:forEach items="${connector.properties}" var="prop">
<p><em>${prop.key}</em>: ${prop.value}</p>
</c:forEach>
<table class="props">
<c:forEach items="${connector.properties}" var="prop">
<tr>
<th>${prop.key}</th>
<td>${prop.value}</td>
</tr>
</c:forEach>
</table>
</td>
</tr>
</c:if>
</table>
</div>
</td>
<td class="remoteRepo">
<div>
<img src="<c:url value="/images/archiva-world.png"/>"/>

<p class="id">${connector.targetRepoId}</p>
</div> <%-- connector --%>

<p class="name">${repoMap[connector.targetRepoId].name}</p>

<p class="url">${repoMap[connector.targetRepoId].url}</p>
</div>
</td>
</tr>
</c:forEach>
</div> <%-- proxyConfig --%>
</c:forEach>
</table>
</div> <%-- admin --%>
</c:otherwise>
</c:choose>


+ 39
- 29
archiva-web/archiva-webapp/src/main/webapp/css/site.css View File

@@ -245,72 +245,82 @@ div.repository {
border-bottom: 1px solid #DFDEDE;
}

tr.proxyConnector {
border-bottom: 1px solid #DFDEDE;
div.proxyConfig {
border: 1px dashed #DFDEDE;
margin-bottom: 15px;
padding: 5px;
}

tr.proxyConnector td.managedRepo div,
tr.proxyConnector td.remoteRepo div {
div.proxyConfig div.managedRepo,
div.proxyConfig div.remoteRepo {
border: 1px dotted gray;
padding: 5px;
background-color: white;
}

tr.proxyConnector td.managedRepo img,
tr.proxyConnector td.remoteRepo img {
div.proxyConfig div.remoteRepo {
margin: 5px;
}

div.proxyConfig div.managedRepo img,
div.proxyConfig div.remoteRepo img {
float: left;
border: 0px;
}

tr.proxyConnector td.managedRepo div p,
tr.proxyConnector td.remoteRepo div p {
div.proxyConfig div.managedRepo p,
div.proxyConfig div.remoteRepo p {
margin: 0px;
margin-left: 40px;
padding: 0px;
}

tr.proxyConnector td.managedRepo div p.id,
tr.proxyConnector td.remoteRepo div p.id {
div.proxyConfig div.managedRepo p.id,
div.proxyConfig div.remoteRepo p.id {
font-family: monospace;
}

tr.proxyConnector td.connector {
padding-left: 10px;
padding-right: 10px;
div.proxyConfig div.connector {
border: 1px solid #aaaaff;
margin-top: 10px;
margin-left: 40px !important;
}

tr.proxyConnector td.connector div.wrap {
margin-left: 10px;
margin-right: 10px;
padding: 5px;
border: 1px solid gray;
background-color: #eeeeee;
div.proxyConfig a.expand {
font-size: 7pt;
color: gray;
}

tr.proxyConnector td.connector div.controls {
div.proxyConfig div.controls {
float: right;
}

tr.proxyConnector td.connector div h4 {
font-size: 1.0em;
div.proxyConfig div.connector h4 {
padding: 3px;
font-size: 8pt;
margin: 0px;
}

tr.proxyConnector td.connector table {
div.proxyConfig div.connector table.settings {
border: 0px;
background-color: transparent;
font-size: 0.8em;
font-size: 8pt;
margin-left: 10px;
}

tr.proxyConnector td.connector table p {
margin: 0px;
padding: 0px;
div.proxyConfig div.connector table.settings th,
div.proxyConfig div.connector table.settings td {
font-size: 8pt;
}

tr.seperator td {
border-top: 1px dashed #dddddd !important;
div.proxyConfig div.connector table.settings table.policies {
border: 1px dotted gray;
}

div.proxyConfig div.connector table p {
margin: 0px;
padding: 0px;
}
div.admin div.dark,
div.admin div.lite {
border: 1px solid #aaaaaa;

BIN
archiva-web/archiva-webapp/src/main/webapp/images/icons/down.gif View File


BIN
archiva-web/archiva-webapp/src/main/webapp/images/icons/up.gif View File


+ 128
- 0
archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/AbstractWebworkTestCase.java View File

@@ -0,0 +1,128 @@
package org.apache.maven.archiva.web.action;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import com.opensymphony.xwork.ActionSupport;

import org.apache.commons.lang.StringUtils;
import org.codehaus.plexus.PlexusTestCase;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;

/**
* AbstractWebworkTestCase
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public abstract class AbstractWebworkTestCase
extends PlexusTestCase
{
/**
* This is a conveinence method for mimicking how the webwork interceptors
* operate on an action, before the request is processed.
*
* Call this before each major request to the action to be sure you mimic the webwork process correctly.
*/
protected void preRequest( ActionSupport action )
{
action.clearErrorsAndMessages();
}

/**
* Tests the action to ensure that it has errors.
*
* NOTE: Don't forget to run {@link #preRequest(ActionSupport)} before each request to your action!
*/
protected void assertHasErrors( ActionSupport action )
{
assertNotNull( action.getActionErrors() );
assertTrue( "Expected an error to occur.", action.getActionErrors().size() > 0 );
}
/**
* Tests the action to ensure that it has messages.
*
* NOTE: Don't forget to run {@link #preRequest(ActionSupport)} before each request to your action!
*/
protected void assertHasMessages( ActionSupport action )
{
assertNotNull( action.getActionMessages() );
assertTrue( "Expected an message to be set.", action.getActionMessages().size() > 0 );
}

/**
* Tests the action to ensure that it has NO errors.
*
* NOTE: Don't forget to run {@link #preRequest(ActionSupport)} before each request to your action!
*/
protected void assertNoErrors( ActionSupport action )
{
List<String> errors = (List<String>) action.getActionErrors();
assertNotNull( errors );
if ( errors.size() > 0 )
{
StringBuffer msg = new StringBuffer();
msg.append( "Should have had no errors. but found the following errors." );
for ( String error : errors )
{
msg.append( "\n " ).append( error );
}
fail( msg.toString() );
}
}

protected void assertRequestStatus( ActionSupport action, String expectedStatus, String methodName )
throws Exception
{
action.clearErrorsAndMessages();
Method method = action.getClass().getDeclaredMethod( methodName, (Class[]) null );
Object actualStatus = method.invoke( action, (Object[]) null );
assertTrue( "return should be of type String", actualStatus instanceof String );
if ( !StringUtils.equals( expectedStatus, (String) actualStatus ) )
{
StringBuffer msg = new StringBuffer();
msg.append( "Unexpected status returned from method <" );
msg.append( methodName ).append( "> on action <" );
String clazzname = action.getClass().getName();
msg.append( clazzname.substring( clazzname.lastIndexOf( '.' ) ) );
msg.append( ">: expected:<" ).append( expectedStatus ).append( "> but was:<" );
msg.append( (String) actualStatus ).append( ">. (see attached action messages and errors below)" );
for ( String message : (Collection<String>) action.getActionMessages() )
{
msg.append( "\n [MESSAGE]: " ).append( message );
}
for ( String error : (Collection<String>) action.getActionErrors() )
{
msg.append( "\n [ERROR]: " ).append( error );
}
fail( msg.toString() );
}
}
}

+ 408
- 0
archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/AddProxyConnectorActionTest.java View File

@@ -0,0 +1,408 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import com.opensymphony.xwork.Action;

import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.IndeterminateConfigurationException;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration;
import org.apache.maven.archiva.policies.CachedFailuresPolicy;
import org.apache.maven.archiva.policies.ChecksumPolicy;
import org.apache.maven.archiva.policies.ReleasesPolicy;
import org.apache.maven.archiva.policies.SnapshotsPolicy;
import org.apache.maven.archiva.web.action.AbstractWebworkTestCase;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
import org.codehaus.plexus.registry.RegistryException;
import org.easymock.MockControl;

import java.util.List;

/**
* AddProxyConnectorActionTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class AddProxyConnectorActionTest
extends AbstractWebworkTestCase
{
private AddProxyConnectorAction action;

private MockControl archivaConfigurationControl;

private ArchivaConfiguration archivaConfiguration;

public void testAddBlackListPattern()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
populateProxyConnector( connector );

// Perform Test w/no values.
preRequest( action );
String status = action.addBlackListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no blacklist pattern added.
assertHasErrors( action );
assertEquals( 0, connector.getBlackListPatterns().size() );

// Try again, but now with a pattern to add.
action.setBlackListPattern( "**/*-javadoc.jar" );
preRequest( action );
status = action.addBlackListPattern();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 blacklist pattern added.
assertNoErrors( action );
assertEquals( 1, connector.getBlackListPatterns().size() );
}

public void testAddProperty()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
populateProxyConnector( connector );

// Perform Test w/no values.
preRequest( action );
String status = action.addProperty();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no property pattern added.
assertHasErrors( action );
assertEquals( 0, connector.getProperties().size() );

// Try again, but now with a property key/value to add.
action.setPropertyKey( "eat-a" );
action.setPropertyValue( "gramov-a-bits" );
preRequest( action );
status = action.addProperty();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 property added.
assertNoErrors( action );
assertEquals( 1, connector.getProperties().size() );
}

public void testAddProxyConnectorCommit()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
populateProxyConnector( connector );

// Create the input screen.
assertRequestStatus( action, Action.SUCCESS, "commit" );
assertNoErrors( action );

// Test configuration.
List<ProxyConnectorConfiguration> proxyConfigs = archivaConfiguration.getConfiguration().getProxyConnectors();
assertNotNull( proxyConfigs );
assertEquals( 1, proxyConfigs.size() );

ProxyConnectorConfiguration actualConnector = proxyConfigs.get( 0 );

assertNotNull( actualConnector );
// The use of "(direct connection)" should result in a proxyId which is <null>.
assertNull( actualConnector.getProxyId() );
assertEquals( "corporate", actualConnector.getSourceRepoId() );
assertEquals( "central", actualConnector.getTargetRepoId() );
}

public void testAddProxyConnectorInitialPage()
throws Exception
{
expectConfigurationRequests( 3 );
archivaConfigurationControl.replay();

action.prepare();
ProxyConnectorConfiguration configuration = action.getConnector();
assertNotNull( configuration );
assertNull( configuration.getProxyId() );
assertNull( configuration.getSourceRepoId() );
assertNull( configuration.getTargetRepoId() );
assertTrue( configuration.getPolicies().isEmpty() );
assertTrue( configuration.getProperties().isEmpty() );
assertTrue( configuration.getBlackListPatterns().isEmpty() );
assertTrue( configuration.getWhiteListPatterns().isEmpty() );

String status = action.input();
assertEquals( Action.INPUT, status );
}

public void testAddWhiteListPattern()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
populateProxyConnector( connector );

// Perform Test w/no values.
preRequest( action );
String status = action.addWhiteListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no whitelist pattern added.
assertHasErrors( action );
assertEquals( 0, connector.getWhiteListPatterns().size() );

// Try again, but now with a pattern to add.
action.setWhiteListPattern( "**/*.jar" );
preRequest( action );
status = action.addWhiteListPattern();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 whitelist pattern added.
assertNoErrors( action );
assertEquals( 1, connector.getWhiteListPatterns().size() );
}

public void testRemoveBlackListPattern()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
populateProxyConnector( connector );

// Add some arbitrary blacklist patterns.
connector.addBlackListPattern( "**/*-javadoc.jar" );
connector.addBlackListPattern( "**/*.war" );

// Perform Test w/no pattern value.
preRequest( action );
String status = action.removeBlackListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no blacklist pattern removed.
assertHasErrors( action );
assertEquals( 2, connector.getBlackListPatterns().size() );

// Perform test w/invalid (non-existant) pattern value to remove.
preRequest( action );
action.setPattern( "**/*oops*" );
status = action.removeBlackListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no blacklist pattern removed.
assertHasErrors( action );
assertEquals( 2, connector.getBlackListPatterns().size() );

// Try again, but now with a valid pattern to remove.
action.setPattern( "**/*-javadoc.jar" );
preRequest( action );
status = action.removeBlackListPattern();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 blacklist pattern left.
assertNoErrors( action );
assertEquals( 1, connector.getBlackListPatterns().size() );
assertEquals( "Should have left 1 blacklist pattern", "**/*.war", connector.getBlackListPatterns().get( 0 ) );
}

public void testRemoveProperty()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
populateProxyConnector( connector );

// Add some arbitrary properties.
connector.addProperty( "username", "general-tso" );
connector.addProperty( "password", "chicken" );

// Perform Test w/no property key.
preRequest( action );
String status = action.removeProperty();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no properties removed.
assertHasErrors( action );
assertEquals( 2, connector.getProperties().size() );

// Perform test w/invalid (non-existant) property key to remove.
preRequest( action );
action.setPropertyKey( "slurm" );
status = action.removeProperty();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no properties removed.
assertHasErrors( action );
assertEquals( 2, connector.getProperties().size() );

// Try again, but now with a valid property to remove.
preRequest( action );
action.setPropertyKey( "password" );
status = action.removeProperty();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 property left.
assertNoErrors( action );
assertEquals( 1, connector.getProperties().size() );
assertEquals( "Should have left 1 property", "general-tso", connector.getProperties().get( "username" ) );
}

public void testRemoveWhiteListPattern()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
populateProxyConnector( connector );

// Add some arbitrary whitelist patterns.
connector.addWhiteListPattern( "javax/**/*" );
connector.addWhiteListPattern( "com/sun/**/*" );

// Perform Test w/no pattern value.
preRequest( action );
String status = action.removeWhiteListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no whitelist pattern removed.
assertHasErrors( action );
assertEquals( 2, connector.getWhiteListPatterns().size() );

// Perform test w/invalid (non-existant) pattern value to remove.
preRequest( action );
action.setPattern( "**/*oops*" );
status = action.removeWhiteListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no whitelist pattern removed.
assertHasErrors( action );
assertEquals( 2, connector.getWhiteListPatterns().size() );

// Try again, but now with a valid pattern to remove.
action.setPattern( "com/sun/**/*" );
preRequest( action );
status = action.removeWhiteListPattern();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 whitelist pattern left.
assertNoErrors( action );
assertEquals( 1, connector.getWhiteListPatterns().size() );
assertEquals( "Should have left 1 whitelist pattern", "javax/**/*", connector.getWhiteListPatterns().get( 0 ) );
}

public void testSecureActionBundle()
throws Exception
{
expectConfigurationRequests( 3 );
archivaConfigurationControl.replay();

action.prepare();
SecureActionBundle bundle = action.getSecureActionBundle();
assertTrue( bundle.requiresAuthentication() );
assertEquals( 1, bundle.getAuthorizationTuples().size() );
}

private Configuration createInitialConfiguration()
{
Configuration config = new Configuration();

ManagedRepositoryConfiguration managedRepo = new ManagedRepositoryConfiguration();
managedRepo.setId( "corporate" );
managedRepo.setLayout( "${java.io.tmpdir}/archiva-test/managed-repo" );
managedRepo.setReleases( true );

config.addManagedRepository( managedRepo );

RemoteRepositoryConfiguration remoteRepo = new RemoteRepositoryConfiguration();
remoteRepo.setId( "central" );
remoteRepo.setUrl( "http://repo1.maven.org/maven2/" );

config.addRemoteRepository( remoteRepo );

return config;
}

private void expectConfigurationRequests( int requestConfigCount )
throws RegistryException, IndeterminateConfigurationException
{
Configuration config = createInitialConfiguration();

for ( int i = 0; i < requestConfigCount; i++ )
{
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( config );
}

archivaConfiguration.save( config );
}

private void populateProxyConnector( ProxyConnectorConfiguration connector )
{
connector.setProxyId( AbstractProxyConnectorFormAction.DIRECT_CONNECTION );
connector.setSourceRepoId( "corporate" );
connector.setTargetRepoId( "central" );

connector.getPolicies().put( "releases", ReleasesPolicy.IGNORED );
connector.getPolicies().put( "snapshots", SnapshotsPolicy.DISABLED );
connector.getPolicies().put( "checksum", ChecksumPolicy.FIX );
connector.getPolicies().put( "cache-failures", CachedFailuresPolicy.IGNORED );
}

@Override
protected void setUp()
throws Exception
{
super.setUp();

action = (AddProxyConnectorAction) lookup( Action.class.getName(), "addProxyConnectorAction" );

archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
action.setArchivaConfiguration( archivaConfiguration );
}
}

+ 0
- 95
archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/ConfigureProxyConnectorActionTest.java View File

@@ -1,95 +0,0 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import com.opensymphony.xwork.Action;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
import org.easymock.MockControl;

/**
* Test the proxy connector configuration action returns the correct data.
*/
public class ConfigureProxyConnectorActionTest
extends PlexusTestCase
{
private ConfigureProxyConnectorAction action;

private MockControl archivaConfigurationControl;

private ArchivaConfiguration archivaConfiguration;

protected void setUp()
throws Exception
{
super.setUp();

// TODO: purely to quiet logging - shouldn't be needed
String appserverBase = getTestFile( "target/appserver-base" ).getAbsolutePath();
System.setProperty( "appserver.base", appserverBase );
action = (ConfigureProxyConnectorAction) lookup( Action.class.getName(), "configureProxyConnectorAction" );

archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
action.setArchivaConfiguration( archivaConfiguration );
}

public void testSecureActionBundle()
throws Exception
{
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( new Configuration() );
archivaConfigurationControl.replay();

action.prepare();
SecureActionBundle bundle = action.getSecureActionBundle();
assertTrue( bundle.requiresAuthentication() );
assertEquals( 1, bundle.getAuthorizationTuples().size() );
}

public void testAddProxyConnectorInitialPage()
throws Exception
{
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( new Configuration() );
archivaConfigurationControl.replay();

action.prepare();
assertNull( action.getMode() );
ProxyConnectorConfiguration configuration = action.getConnector();
assertNotNull( configuration );
assertNull( configuration.getProxyId() );
assertNull( configuration.getSourceRepoId() );
assertNull( configuration.getTargetRepoId() );
assertTrue( configuration.getPolicies().isEmpty() );
assertTrue( configuration.getProperties().isEmpty() );
assertTrue( configuration.getBlackListPatterns().isEmpty() );
assertTrue( configuration.getWhiteListPatterns().isEmpty() );

String status = action.add();
assertEquals( Action.INPUT, status );
}

// TODO: test the population of proxyIdOptions, *RepoIdList (from prepare) and policyMap (from initialize)
// TODO: test the other methods. Should review the structure of the action in the process as there is a lot of different combinations of parameters
}

+ 225
- 0
archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/DeleteProxyConnectorActionTest.java View File

@@ -0,0 +1,225 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import com.opensymphony.xwork.Action;

import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.IndeterminateConfigurationException;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration;
import org.apache.maven.archiva.web.action.AbstractWebworkTestCase;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
import org.codehaus.plexus.registry.RegistryException;
import org.easymock.MockControl;

/**
* DeleteProxyConnectorActionTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DeleteProxyConnectorActionTest
extends AbstractWebworkTestCase
{
private static final String TEST_TARGET_ID = "central";

private static final String TEST_SOURCE_ID = "corporate";

private DeleteProxyConnectorAction action;

private MockControl archivaConfigurationControl;

private ArchivaConfiguration archivaConfiguration;

public void testConfirmDelete()
throws Exception
{
expectConfigurationRequests( 1 );
archivaConfigurationControl.replay();

// Show the confirm the delete of proxy connector screen.
preRequest( action );
action.setSourceId( TEST_SOURCE_ID );
action.setTargetId( TEST_TARGET_ID );
String status = action.confirmDelete();
assertEquals( Action.INPUT, status );
assertNoErrors( action );
}

public void testConfirmDeleteBadSourceOrTarget()
throws Exception
{
expectConfigurationRequests( 4 );
archivaConfigurationControl.replay();

// Attempt to show the confirm delete screen, but provide
// a bad source id or target id to actually delete

preRequest( action );
action.setSourceId( "bad-source" ); // id doesn't exist.
action.setTargetId( "bad-target" ); // id doesn't exist.
String status = action.confirmDelete();
// Should have resulted in an error.
assertEquals( Action.ERROR, status );
assertHasErrors( action );

preRequest( action );
action.setSourceId( "bad" ); // Bad doesn't exist.
action.setTargetId( TEST_TARGET_ID );
status = action.confirmDelete();
// Should have resulted in an error.
assertEquals( Action.ERROR, status );
assertHasErrors( action );

preRequest( action );
action.setSourceId( TEST_SOURCE_ID );
action.setTargetId( "bad" ); // Bad doesn't exist.
status = action.confirmDelete();
// Should have resulted in an error.
assertEquals( Action.ERROR, status );
assertHasErrors( action );
}

public void testConfirmDeleteNoSourceOrTarget()
throws Exception
{
expectConfigurationRequests( 1 );
archivaConfigurationControl.replay();

// Attempt to show the confirm delete screen, but don't provide
// the source id or target id to actually delete

preRequest( action );
action.setSourceId( null ); // No source Id.
action.setTargetId( null ); // No target Id.
String status = action.confirmDelete();
// Should have resulted in an error.
assertEquals( Action.ERROR, status );
assertHasErrors( action );

preRequest( action );
action.setSourceId( TEST_SOURCE_ID );
action.setTargetId( null ); // No target Id.
status = action.confirmDelete();
// Should have resulted in an error.
assertEquals( Action.ERROR, status );
assertHasErrors( action );

preRequest( action );
action.setSourceId( null ); // No source Id.
action.setTargetId( TEST_TARGET_ID );
status = action.confirmDelete();
// Should have resulted in an error.
assertEquals( Action.ERROR, status );
assertHasErrors( action );
}

public void testDelete()
throws Exception
{
expectConfigurationRequests( 5 );
archivaConfigurationControl.replay();

// Show the confirm the delete of proxy connector screen.
preRequest( action );
action.setSourceId( TEST_SOURCE_ID );
action.setTargetId( TEST_TARGET_ID );
String status = action.confirmDelete();
assertEquals( Action.INPUT, status );
assertNoErrors( action );

// Perform the delete.
preRequest( action );
status = action.delete();
assertEquals( Action.SUCCESS, status );
assertNoErrors( action );
assertHasMessages( action );

// Test the configuration.
assertEquals( 0, archivaConfiguration.getConfiguration().getProxyConnectors().size() );
}

public void testSecureActionBundle()
throws Exception
{
expectConfigurationRequests( 1 );
archivaConfigurationControl.replay();

SecureActionBundle bundle = action.getSecureActionBundle();
assertTrue( bundle.requiresAuthentication() );
assertEquals( 1, bundle.getAuthorizationTuples().size() );
}

private Configuration createInitialConfiguration()
{
Configuration config = new Configuration();

ManagedRepositoryConfiguration managedRepo = new ManagedRepositoryConfiguration();
managedRepo.setId( TEST_SOURCE_ID );
managedRepo.setLayout( "${java.io.tmpdir}/archiva-test/managed-repo" );
managedRepo.setReleases( true );

config.addManagedRepository( managedRepo );

RemoteRepositoryConfiguration remoteRepo = new RemoteRepositoryConfiguration();
remoteRepo.setId( TEST_TARGET_ID );
remoteRepo.setUrl( "http://repo1.maven.org/maven2/" );

config.addRemoteRepository( remoteRepo );

ProxyConnectorConfiguration connector = new ProxyConnectorConfiguration();
connector.setSourceRepoId( TEST_SOURCE_ID );
connector.setTargetRepoId( TEST_TARGET_ID );

config.addProxyConnector( connector );

return config;
}

private void expectConfigurationRequests( int requestConfigCount )
throws RegistryException, IndeterminateConfigurationException
{
Configuration config = createInitialConfiguration();

for ( int i = 0; i < requestConfigCount; i++ )
{
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( config );
}

archivaConfiguration.save( config );
}

@Override
protected void setUp()
throws Exception
{
super.setUp();

action = (DeleteProxyConnectorAction) lookup( Action.class.getName(), "deleteProxyConnectorAction" );

archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
action.setArchivaConfiguration( archivaConfiguration );
}
}

+ 436
- 0
archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/EditProxyConnectorActionTest.java View File

@@ -0,0 +1,436 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import com.opensymphony.xwork.Action;

import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.IndeterminateConfigurationException;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration;
import org.apache.maven.archiva.policies.CachedFailuresPolicy;
import org.apache.maven.archiva.policies.ChecksumPolicy;
import org.apache.maven.archiva.policies.ReleasesPolicy;
import org.apache.maven.archiva.policies.SnapshotsPolicy;
import org.apache.maven.archiva.web.action.AbstractWebworkTestCase;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
import org.codehaus.plexus.registry.RegistryException;
import org.easymock.MockControl;

import java.util.List;

/**
* EditProxyConnectorActionTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class EditProxyConnectorActionTest
extends AbstractWebworkTestCase
{
private static final String TEST_TARGET_ID = "central";

private static final String TEST_SOURCE_ID = "corporate";

private EditProxyConnectorAction action;

private MockControl archivaConfigurationControl;

private ArchivaConfiguration archivaConfiguration;

public void testAddBlackListPattern()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.setSource( TEST_SOURCE_ID );
action.setTarget( TEST_TARGET_ID );
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
assertInitialProxyConnector( connector );

// Perform Test w/no values.
preRequest( action );
String status = action.addBlackListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no blacklist pattern added.
assertHasErrors( action );
assertEquals( 0, connector.getBlackListPatterns().size() );

// Try again, but now with a pattern to add.
action.setBlackListPattern( "**/*-javadoc.jar" );
preRequest( action );
status = action.addBlackListPattern();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 blacklist pattern added.
assertNoErrors( action );
assertEquals( 1, connector.getBlackListPatterns().size() );
}

public void testAddProperty()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.setSource( TEST_SOURCE_ID );
action.setTarget( TEST_TARGET_ID );
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
assertInitialProxyConnector( connector );

// Perform Test w/no values.
preRequest( action );
String status = action.addProperty();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no property pattern added.
assertHasErrors( action );
assertEquals( 0, connector.getProperties().size() );

// Try again, but now with a property key/value to add.
action.setPropertyKey( "eat-a" );
action.setPropertyValue( "gramov-a-bits" );
preRequest( action );
status = action.addProperty();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 property added.
assertNoErrors( action );
assertEquals( 1, connector.getProperties().size() );
}

public void testAddWhiteListPattern()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.setSource( TEST_SOURCE_ID );
action.setTarget( TEST_TARGET_ID );
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
assertInitialProxyConnector( connector );

// Perform Test w/no values.
preRequest( action );
String status = action.addWhiteListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no whitelist pattern added.
assertHasErrors( action );
assertEquals( 0, connector.getWhiteListPatterns().size() );

// Try again, but now with a pattern to add.
action.setWhiteListPattern( "**/*.jar" );
preRequest( action );
status = action.addWhiteListPattern();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 whitelist pattern added.
assertNoErrors( action );
assertEquals( 1, connector.getWhiteListPatterns().size() );
}

public void testEditProxyConnectorCommit()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.setSource( TEST_SOURCE_ID );
action.setTarget( TEST_TARGET_ID );
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
assertInitialProxyConnector( connector );

// Create the input screen.
assertRequestStatus( action, Action.SUCCESS, "commit" );
assertNoErrors( action );

// Test configuration.
List<ProxyConnectorConfiguration> proxyConfigs = archivaConfiguration.getConfiguration().getProxyConnectors();
assertNotNull( proxyConfigs );
assertEquals( 1, proxyConfigs.size() );

ProxyConnectorConfiguration actualConnector = proxyConfigs.get( 0 );

assertNotNull( actualConnector );
// The use of "(direct connection)" should result in a proxyId which is <null>.
assertNull( actualConnector.getProxyId() );
assertEquals( "corporate", actualConnector.getSourceRepoId() );
assertEquals( "central", actualConnector.getTargetRepoId() );
}

public void testEditProxyConnectorInitialPage()
throws Exception
{
expectConfigurationRequests( 3 );
archivaConfigurationControl.replay();

action.setSource( TEST_SOURCE_ID );
action.setTarget( TEST_TARGET_ID );
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
assertInitialProxyConnector( connector );

String status = action.input();
assertEquals( Action.INPUT, status );
}

public void testRemoveBlackListPattern()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.setSource( TEST_SOURCE_ID );
action.setTarget( TEST_TARGET_ID );
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
assertInitialProxyConnector( connector );

// Add some arbitrary blacklist patterns.
connector.addBlackListPattern( "**/*-javadoc.jar" );
connector.addBlackListPattern( "**/*.war" );

// Perform Test w/no pattern value.
preRequest( action );
String status = action.removeBlackListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no blacklist pattern removed.
assertHasErrors( action );
assertEquals( 2, connector.getBlackListPatterns().size() );

// Perform test w/invalid (non-existant) pattern value to remove.
preRequest( action );
action.setPattern( "**/*oops*" );
status = action.removeBlackListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no blacklist pattern removed.
assertHasErrors( action );
assertEquals( 2, connector.getBlackListPatterns().size() );

// Try again, but now with a valid pattern to remove.
action.setPattern( "**/*-javadoc.jar" );
preRequest( action );
status = action.removeBlackListPattern();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 blacklist pattern left.
assertNoErrors( action );
assertEquals( 1, connector.getBlackListPatterns().size() );
assertEquals( "Should have left 1 blacklist pattern", "**/*.war", connector.getBlackListPatterns().get( 0 ) );
}

public void testRemoveProperty()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.setSource( TEST_SOURCE_ID );
action.setTarget( TEST_TARGET_ID );
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
assertInitialProxyConnector( connector );

// Add some arbitrary properties.
connector.addProperty( "username", "general-tso" );
connector.addProperty( "password", "chicken" );

// Perform Test w/no property key.
preRequest( action );
String status = action.removeProperty();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no properties removed.
assertHasErrors( action );
assertEquals( 2, connector.getProperties().size() );

// Perform test w/invalid (non-existant) property key to remove.
preRequest( action );
action.setPropertyKey( "slurm" );
status = action.removeProperty();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no properties removed.
assertHasErrors( action );
assertEquals( 2, connector.getProperties().size() );

// Try again, but now with a valid property to remove.
preRequest( action );
action.setPropertyKey( "password" );
status = action.removeProperty();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 property left.
assertNoErrors( action );
assertEquals( 1, connector.getProperties().size() );
assertEquals( "Should have left 1 property", "general-tso", connector.getProperties().get( "username" ) );
}

public void testRemoveWhiteListPattern()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Prepare Test.
action.setSource( TEST_SOURCE_ID );
action.setTarget( TEST_TARGET_ID );
action.prepare();
ProxyConnectorConfiguration connector = action.getConnector();
assertInitialProxyConnector( connector );

// Add some arbitrary whitelist patterns.
connector.addWhiteListPattern( "javax/**/*" );
connector.addWhiteListPattern( "com/sun/**/*" );

// Perform Test w/no pattern value.
preRequest( action );
String status = action.removeWhiteListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no whitelist pattern removed.
assertHasErrors( action );
assertEquals( 2, connector.getWhiteListPatterns().size() );

// Perform test w/invalid (non-existant) pattern value to remove.
preRequest( action );
action.setPattern( "**/*oops*" );
status = action.removeWhiteListPattern();
assertEquals( Action.INPUT, status );

// Should have returned an error, with no whitelist pattern removed.
assertHasErrors( action );
assertEquals( 2, connector.getWhiteListPatterns().size() );

// Try again, but now with a valid pattern to remove.
action.setPattern( "com/sun/**/*" );
preRequest( action );
status = action.removeWhiteListPattern();
assertEquals( Action.INPUT, status );

// Should have no error, and 1 whitelist pattern left.
assertNoErrors( action );
assertEquals( 1, connector.getWhiteListPatterns().size() );
assertEquals( "Should have left 1 whitelist pattern", "javax/**/*", connector.getWhiteListPatterns().get( 0 ) );
}

public void testSecureActionBundle()
throws Exception
{
archivaConfigurationControl.replay();

action.prepare();
SecureActionBundle bundle = action.getSecureActionBundle();
assertTrue( bundle.requiresAuthentication() );
assertEquals( 1, bundle.getAuthorizationTuples().size() );
}

private void assertInitialProxyConnector( ProxyConnectorConfiguration connector )
{
assertNotNull( connector );
assertNotNull( connector.getBlackListPatterns() );
assertNotNull( connector.getWhiteListPatterns() );
assertNotNull( connector.getProperties() );

assertEquals( TEST_SOURCE_ID, connector.getSourceRepoId() );
assertEquals( TEST_TARGET_ID, connector.getTargetRepoId() );
}

private Configuration createInitialConfiguration()
{
Configuration config = new Configuration();

ManagedRepositoryConfiguration managedRepo = new ManagedRepositoryConfiguration();
managedRepo.setId( TEST_SOURCE_ID );
managedRepo.setLayout( "${java.io.tmpdir}/archiva-test/managed-repo" );
managedRepo.setReleases( true );

config.addManagedRepository( managedRepo );

RemoteRepositoryConfiguration remoteRepo = new RemoteRepositoryConfiguration();
remoteRepo.setId( TEST_TARGET_ID );
remoteRepo.setUrl( "http://repo1.maven.org/maven2/" );

config.addRemoteRepository( remoteRepo );

ProxyConnectorConfiguration connector = new ProxyConnectorConfiguration();
connector.setSourceRepoId( TEST_SOURCE_ID );
connector.setTargetRepoId( TEST_TARGET_ID );
connector.getPolicies().put( "releases", ReleasesPolicy.IGNORED );
connector.getPolicies().put( "snapshots", SnapshotsPolicy.DISABLED );
connector.getPolicies().put( "checksum", ChecksumPolicy.FIX );
connector.getPolicies().put( "cache-failures", CachedFailuresPolicy.IGNORED );

config.addProxyConnector( connector );

return config;
}

private void expectConfigurationRequests( int requestConfigCount )
throws RegistryException, IndeterminateConfigurationException
{
Configuration config = createInitialConfiguration();

for ( int i = 0; i < requestConfigCount; i++ )
{
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( config );
}

archivaConfiguration.save( config );
}

@Override
protected void setUp()
throws Exception
{
super.setUp();

action = (EditProxyConnectorAction) lookup( Action.class.getName(), "editProxyConnectorAction" );

archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
action.setArchivaConfiguration( archivaConfiguration );

/* Configuration will be requested at least 3 times. */
for ( int i = 0; i < 3; i++ )
{
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( new Configuration() );
}
}
}

+ 151
- 0
archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/ProxyConnectorsActionTest.java View File

@@ -0,0 +1,151 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import com.opensymphony.xwork.Action;

import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.IndeterminateConfigurationException;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration;
import org.apache.maven.archiva.web.action.AbstractWebworkTestCase;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
import org.codehaus.plexus.registry.RegistryException;
import org.easymock.MockControl;

/**
* ProxyConnectorsActionTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ProxyConnectorsActionTest
extends AbstractWebworkTestCase
{
private static final String JAVAX = "javax";

private static final String CENTRAL = "central";

private static final String CORPORATE = "corporate";

private ProxyConnectorsAction action;

private MockControl archivaConfigurationControl;

private ArchivaConfiguration archivaConfiguration;

@Override
protected void setUp()
throws Exception
{
super.setUp();

action = (ProxyConnectorsAction) lookup( Action.class.getName(), "proxyConnectorsAction" );

archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
action.setArchivaConfiguration( archivaConfiguration );
}

public void testSecureActionBundle()
throws Exception
{
expectConfigurationRequests( 3 );
archivaConfigurationControl.replay();

action.prepare();
SecureActionBundle bundle = action.getSecureActionBundle();
assertTrue( bundle.requiresAuthentication() );
assertEquals( 1, bundle.getAuthorizationTuples().size() );
}

public void testExecute()
throws Exception
{
expectConfigurationRequests( 3 );
archivaConfigurationControl.replay();

action.prepare();

String status = action.execute();
assertEquals( Action.SUCCESS, status );
assertNoErrors( action );
assertNotNull( action.getProxyConnectorMap() );
assertNotNull( action.getRepoMap() );

assertEquals( 1, action.getProxyConnectorMap().size() );
assertEquals( 3, action.getRepoMap().size() );
}

private void expectConfigurationRequests( int requestConfigCount )
throws RegistryException, IndeterminateConfigurationException
{
Configuration config = createInitialConfiguration();

for ( int i = 0; i < requestConfigCount; i++ )
{
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( config );
}

archivaConfiguration.save( config );
}

private Configuration createInitialConfiguration()
{
Configuration config = new Configuration();

ManagedRepositoryConfiguration managedRepo = new ManagedRepositoryConfiguration();
managedRepo.setId( CORPORATE );
managedRepo.setLayout( "${java.io.tmpdir}/archiva-test/managed-repo" );
managedRepo.setReleases( true );

config.addManagedRepository( managedRepo );

RemoteRepositoryConfiguration remoteRepo = new RemoteRepositoryConfiguration();
remoteRepo.setId( CENTRAL );
remoteRepo.setUrl( "http://repo1.maven.org/maven2/" );

config.addRemoteRepository( remoteRepo );

remoteRepo = new RemoteRepositoryConfiguration();
remoteRepo.setId( JAVAX );
remoteRepo.setUrl( "http://download.java.net/maven/2/" );

config.addRemoteRepository( remoteRepo );

ProxyConnectorConfiguration connector = new ProxyConnectorConfiguration();
connector.setSourceRepoId( CORPORATE );
connector.setTargetRepoId( CENTRAL );

config.addProxyConnector( connector );

connector = new ProxyConnectorConfiguration();
connector.setSourceRepoId( CORPORATE );
connector.setTargetRepoId( JAVAX );

config.addProxyConnector( connector );

return config;
}
}

+ 253
- 0
archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/connectors/proxy/SortProxyConnectorsActionTest.java View File

@@ -0,0 +1,253 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import com.opensymphony.xwork.Action;

import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.IndeterminateConfigurationException;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration;
import org.apache.maven.archiva.configuration.functors.ProxyConnectorConfigurationOrderComparator;
import org.apache.maven.archiva.web.action.AbstractWebworkTestCase;
import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
import org.codehaus.plexus.registry.RegistryException;
import org.easymock.MockControl;

import java.util.Collections;
import java.util.List;

/**
* SortProxyConnectorsActionTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class SortProxyConnectorsActionTest
extends AbstractWebworkTestCase
{
private static final String JAVAX = "javax";

private static final String CENTRAL = "central";

private static final String CORPORATE = "corporate";

private static final String CODEHAUS = "codehaus";

private SortProxyConnectorsAction action;

private MockControl archivaConfigurationControl;

private ArchivaConfiguration archivaConfiguration;

public void testSecureActionBundle()
throws Exception
{
expectConfigurationRequests( 1 );
archivaConfigurationControl.replay();

SecureActionBundle bundle = action.getSecureActionBundle();
assertTrue( bundle.requiresAuthentication() );
assertEquals( 1, bundle.getAuthorizationTuples().size() );
}

public void testSortDown()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

action.setSource( CORPORATE );
action.setTarget( CENTRAL );
String status = action.sortDown();
assertEquals( Action.SUCCESS, status );

assertOrder( new String[] { JAVAX, CENTRAL, CODEHAUS } );
}

public void testSortDownPastEnd()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Ask the last connector to sort down (essentially a no-op)
action.setSource( CORPORATE );
action.setTarget( CODEHAUS );
String status = action.sortDown();
assertEquals( Action.SUCCESS, status );

// No order change.
assertOrder( new String[] { CENTRAL, JAVAX, CODEHAUS } );
}

public void testSortUp()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

action.setSource( CORPORATE );
action.setTarget( CODEHAUS );
String status = action.sortUp();
assertEquals( Action.SUCCESS, status );

assertOrder( new String[] { CENTRAL, CODEHAUS, JAVAX } );
}

public void testSortUpPastBeginning()
throws Exception
{
expectConfigurationRequests( 7 );
archivaConfigurationControl.replay();

// Ask the first connector to sort up (essentially a no-op)
action.setSource( CORPORATE );
action.setTarget( CENTRAL );
String status = action.sortUp();
assertEquals( Action.SUCCESS, status );

// No order change.
assertOrder( new String[] { CENTRAL, JAVAX, CODEHAUS } );
}

private void assertOrder( String[] targetRepoOrder )
{
List<ProxyConnectorConfiguration> connectors = archivaConfiguration.getConfiguration().getProxyConnectors();
Collections.sort( connectors, ProxyConnectorConfigurationOrderComparator.getInstance() );

for ( ProxyConnectorConfiguration connector : connectors )
{
assertEquals( "All connectors in list should have the same source id (in this test)", CORPORATE, connector
.getSourceRepoId() );
}

assertEquals( targetRepoOrder.length, connectors.size() );

int orderFailedAt = ( -1 );
for ( int i = 0; i < targetRepoOrder.length; i++ )
{
if ( !StringUtils.equals( targetRepoOrder[i], connectors.get( i ).getTargetRepoId() ) )
{
orderFailedAt = i;
break;
}
}

if ( orderFailedAt >= 0 )
{
StringBuffer msg = new StringBuffer();

msg.append( "Failed expected order of the proxy connectors <" );
msg.append( StringUtils.join( targetRepoOrder, ", " ) );
msg.append( ">, actual <" );

boolean needsComma = false;
for ( ProxyConnectorConfiguration proxy : connectors )
{
if ( needsComma )
{
msg.append( ", " );
}
msg.append( proxy.getTargetRepoId() );
needsComma = true;
}
msg.append( "> failure at index <" ).append( orderFailedAt ).append( ">." );

fail( msg.toString() );
}
}

private Configuration createInitialConfiguration()
{
Configuration config = new Configuration();

ManagedRepositoryConfiguration managedRepo = new ManagedRepositoryConfiguration();
managedRepo.setId( CORPORATE );
managedRepo.setLayout( "${java.io.tmpdir}/archiva-test/managed-repo" );
managedRepo.setReleases( true );
config.addManagedRepository( managedRepo );

RemoteRepositoryConfiguration remoteRepo = new RemoteRepositoryConfiguration();
remoteRepo.setId( CENTRAL );
remoteRepo.setUrl( "http://repo1.maven.org/maven2/" );
config.addRemoteRepository( remoteRepo );

remoteRepo = new RemoteRepositoryConfiguration();
remoteRepo.setId( JAVAX );
remoteRepo.setUrl( "http://download.java.net/maven/2/" );
config.addRemoteRepository( remoteRepo );

remoteRepo = new RemoteRepositoryConfiguration();
remoteRepo.setId( CODEHAUS );
remoteRepo.setUrl( "http://repository.codehaus.org/" );
config.addRemoteRepository( remoteRepo );

ProxyConnectorConfiguration connector = new ProxyConnectorConfiguration();
connector.setSourceRepoId( CORPORATE );
connector.setTargetRepoId( CENTRAL );
connector.setOrder( 1 );
config.addProxyConnector( connector );

connector = new ProxyConnectorConfiguration();
connector.setSourceRepoId( CORPORATE );
connector.setTargetRepoId( JAVAX );
connector.setOrder( 2 );
config.addProxyConnector( connector );

connector = new ProxyConnectorConfiguration();
connector.setSourceRepoId( CORPORATE );
connector.setTargetRepoId( CODEHAUS );
connector.setOrder( 3 );
config.addProxyConnector( connector );

return config;
}

private void expectConfigurationRequests( int requestConfigCount )
throws RegistryException, IndeterminateConfigurationException
{
Configuration config = createInitialConfiguration();

for ( int i = 0; i < requestConfigCount; i++ )
{
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( config );
}

archivaConfiguration.save( config );
}

@Override
protected void setUp()
throws Exception
{
super.setUp();

action = (SortProxyConnectorsAction) lookup( Action.class.getName(), "sortProxyConnectorsAction" );

archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
action.setArchivaConfiguration( archivaConfiguration );
}
}

+ 6
- 2
archiva-web/archiva-webapp/src/test/resources/log4j.xml View File

@@ -12,7 +12,11 @@

<!-- Help identify bugs during testing -->
<logger name="org.apache.maven.archiva">
<level value="debug"/>
<level value="info"/>
</logger>
<logger name="net.sf.ehcache">
<level value="warn"/>
</logger>

<logger name="org.codehaus.plexus.security">
@@ -40,7 +44,7 @@
</logger>

<root>
<priority value ="debug" />
<priority value ="info" />
<appender-ref ref="console" />
</root>


archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/action/admin/connectors/proxy/ConfigureProxyConnectorActionTest.xml → archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/action/admin/connectors/proxy/AddProxyConnectorActionTest.xml View File

@@ -24,22 +24,27 @@
<implementation>org.codehaus.plexus.logging.slf4j.Slf4jLoggerManager</implementation>
<lifecycle-handler>basic</lifecycle-handler>
</component>
<component>
<role>com.opensymphony.xwork.Action</role>
<role-hint>configureProxyConnectorAction</role-hint>
<implementation>org.apache.maven.archiva.web.action.admin.connectors.proxy.ConfigureProxyConnectorAction
</implementation>
<instantiation-strategy>per-lookup</instantiation-strategy>
<requirements>
<requirement>
<role>org.apache.maven.archiva.policies.PreDownloadPolicy</role>
<field-name>preDownloadPolicyMap</field-name>
</requirement>
<requirement>
<role>org.apache.maven.archiva.policies.PostDownloadPolicy</role>
<field-name>postDownloadPolicyMap</field-name>
</requirement>
</requirements>
</component>
<role>org.codehaus.plexus.cache.Cache</role>
<role-hint>url-failures-cache</role-hint>
<implementation>org.codehaus.plexus.cache.ehcache.EhcacheCache</implementation>
<description>URL Failure Cache</description>
<configuration>
<disk-expiry-thread-interval-seconds>600</disk-expiry-thread-interval-seconds>
<disk-persistent>false</disk-persistent> <!--disabling disk persistence for unit testing. -->
<disk-store-path>${java.io.tmpdir}/archiva/urlcache</disk-store-path>
<eternal>false</eternal>
<max-elements-in-memory>1000</max-elements-in-memory>
<memory-eviction-policy>LRU</memory-eviction-policy>
<name>url-failures-cache</name>
<overflow-to-disk>false</overflow-to-disk>
<!-- 45 minutes = 2700 seconds -->
<time-to-idle-seconds>2700</time-to-idle-seconds>
<!-- 30 minutes = 1800 seconds -->
<time-to-live-seconds>1800</time-to-live-seconds>
</configuration>
</component>
</components>
</plexus>

+ 50
- 0
archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/action/admin/connectors/proxy/EditProxyConnectorActionTest.xml View File

@@ -0,0 +1,50 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->

<plexus>
<components>
<component>
<role>org.codehaus.plexus.logging.LoggerManager</role>
<implementation>org.codehaus.plexus.logging.slf4j.Slf4jLoggerManager</implementation>
<lifecycle-handler>basic</lifecycle-handler>
</component>
<component>
<role>org.codehaus.plexus.cache.Cache</role>
<role-hint>url-failures-cache</role-hint>
<implementation>org.codehaus.plexus.cache.ehcache.EhcacheCache</implementation>
<description>URL Failure Cache</description>
<configuration>
<disk-expiry-thread-interval-seconds>600</disk-expiry-thread-interval-seconds>
<disk-persistent>false</disk-persistent> <!--disabling disk persistence for unit testing. -->
<disk-store-path>${java.io.tmpdir}/archiva/urlcache</disk-store-path>
<eternal>false</eternal>
<max-elements-in-memory>1000</max-elements-in-memory>
<memory-eviction-policy>LRU</memory-eviction-policy>
<name>url-failures-cache</name>
<overflow-to-disk>false</overflow-to-disk>
<!-- 45 minutes = 2700 seconds -->
<time-to-idle-seconds>2700</time-to-idle-seconds>
<!-- 30 minutes = 1800 seconds -->
<time-to-live-seconds>1800</time-to-live-seconds>
</configuration>
</component>
</components>
</plexus>

Loading…
Cancel
Save