Explorar el Código

[MRM-1551] add rest method to delete artifact.

reuse service in webapp action to avoid too much duplicate code.

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1200019 13f79535-47bb-0310-9956-ffa450edef68
tags/archiva-1.4-M2
Olivier Lamy hace 12 años
padre
commit
609cdaabe9

+ 51
- 2
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java Ver fichero

@@ -606,11 +606,10 @@ public class DefaultRepositoriesService
}
}


public Boolean deleteArtifact( Artifact artifact, String repositoryId )
throws ArchivaRestServiceException
{
String userName = getAuditInformation().getUser().getUsername();
String userName = (String) getAuditInformation().getUser().getPrincipal();
if ( StringUtils.isBlank( userName ) )
{
// TODO use constants from a class instead of magic number
@@ -821,6 +820,56 @@ public class DefaultRepositoriesService
auditListener.auditEvent( auditEvent );
}
}

public ManagedRepositoryAdmin getManagedRepositoryAdmin()
{
return managedRepositoryAdmin;
}

public void setManagedRepositoryAdmin( ManagedRepositoryAdmin managedRepositoryAdmin )
{
this.managedRepositoryAdmin = managedRepositoryAdmin;
}

public RepositoryContentFactory getRepositoryFactory()
{
return repositoryFactory;
}

public void setRepositoryFactory( RepositoryContentFactory repositoryFactory )
{
this.repositoryFactory = repositoryFactory;
}

public RepositorySessionFactory getRepositorySessionFactory()
{
return repositorySessionFactory;
}

public void setRepositorySessionFactory( RepositorySessionFactory repositorySessionFactory )
{
this.repositorySessionFactory = repositorySessionFactory;
}

public List<RepositoryListener> getListeners()
{
return listeners;
}

public void setListeners( List<RepositoryListener> listeners )
{
this.listeners = listeners;
}

public ArchivaAdministration getArchivaAdministration()
{
return archivaAdministration;
}

public void setArchivaAdministration( ArchivaAdministration archivaAdministration )
{
this.archivaAdministration = archivaAdministration;
}
}



+ 6
- 0
archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/archiva/web/action/AbstractActionSupport.java Ver fichero

@@ -32,6 +32,7 @@ import org.apache.commons.lang.math.NumberUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.SessionAware;
import org.codehaus.plexus.redback.users.User;
import org.codehaus.redback.rest.services.RedbackRequestInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
@@ -192,6 +193,11 @@ public abstract class AbstractActionSupport
return auditInformation;
}

protected RedbackRequestInformation getRedbackRequestInformation()
{
return new RedbackRequestInformation( new SimpleUser( getPrincipal() ), getRemoteAddr() );
}

public String getArchivaVersion()
{
return (String) archivaRuntimeProperties.get( "archiva.version" );

+ 30
- 238
archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/archiva/web/action/DeleteArtifactAction.java Ver fichero

@@ -21,53 +21,26 @@ package org.apache.archiva.web.action;

import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.Validateable;
import org.apache.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.beans.ManagedRepository;
import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
import org.apache.archiva.audit.AuditEvent;
import org.apache.archiva.audit.Auditable;
import org.apache.archiva.checksum.ChecksumAlgorithm;
import org.apache.archiva.checksum.ChecksummedFile;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
import org.apache.archiva.metadata.repository.MetadataResolutionException;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.repository.events.RepositoryListener;
import org.apache.archiva.common.utils.VersionUtil;
import org.apache.archiva.rest.api.model.Artifact;
import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.RepositoriesService;
import org.apache.archiva.security.AccessDeniedException;
import org.apache.archiva.security.ArchivaSecurityException;
import org.apache.archiva.security.PrincipalNotFoundException;
import org.apache.archiva.security.UserRepositories;
import org.apache.commons.lang.StringUtils;
import org.apache.archiva.common.utils.VersionComparator;
import org.apache.archiva.common.utils.VersionUtil;
import org.apache.archiva.model.ArchivaRepositoryMetadata;
import org.apache.archiva.model.VersionedReference;
import org.apache.archiva.repository.ContentNotFoundException;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.RepositoryContentFactory;
import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.RepositoryNotFoundException;
import org.apache.archiva.repository.metadata.MetadataTools;
import org.apache.archiva.repository.metadata.RepositoryMetadataException;
import org.apache.archiva.repository.metadata.RepositoryMetadataReader;
import org.apache.archiva.repository.metadata.RepositoryMetadataWriter;
import org.codehaus.redback.rest.services.RedbackAuthenticationThreadLocal;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
* Delete an artifact. Metadata will be updated if one exists, otherwise it would be created.
@@ -95,13 +68,13 @@ public class DeleteArtifactAction

/**
* @since 1.4-M2
* The classifier of the artifact to be deleted (optionnal)
* The classifier of the artifact to be deleted (optionnal)
*/
private String classifier;

/**
* @since 1.4-M2
* The type of the artifact to be deleted (optionnal) (default jar)
* The type of the artifact to be deleted (optionnal) (default jar)
*/
private String type;

@@ -119,13 +92,10 @@ public class DeleteArtifactAction
private UserRepositories userRepositories;

@Inject
private RepositoryContentFactory repositoryFactory;

@Inject
private List<RepositoryListener> listeners;
private ManagedRepositoryAdmin managedRepositoryAdmin;

@Inject
private ManagedRepositoryAdmin managedRepositoryAdmin;
private RepositoriesService repositoriesService;

private ChecksumAlgorithm[] algorithms = new ChecksumAlgorithm[]{ ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 };

@@ -229,128 +199,27 @@ public class DeleteArtifactAction

public String doDelete()
{
RepositorySession repositorySession = repositorySessionFactory.createSession();
// services need a ThreadLocal variable to test karma
RedbackAuthenticationThreadLocal.set( getRedbackRequestInformation() );
try
{
Date lastUpdatedTimestamp = Calendar.getInstance().getTime();

TimeZone timezone = TimeZone.getTimeZone( "UTC" );
DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
fmt.setTimeZone( timezone );
ManagedRepository repoConfig = getManagedRepositoryAdmin().getManagedRepository( repositoryId );

VersionedReference ref = new VersionedReference();
ref.setArtifactId( artifactId );
ref.setGroupId( groupId );
ref.setVersion( version );

ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );

if ( StringUtils.isNotBlank( classifier ) )
{
if (StringUtils.isBlank( type ))
{
addFieldError( "type", "You must configure a type when using classifier" );
return INPUT;
}
ArtifactReference artifactReference = new ArtifactReference();
artifactReference.setArtifactId( artifactId );
artifactReference.setGroupId( groupId );
artifactReference.setVersion( version );
artifactReference.setClassifier( classifier );
artifactReference.setType( type );
repository.deleteArtifact( artifactReference );

String msg = "Artifact \'" + groupId + ":" + artifactId + ":" + classifier + ":" + version
+ "\' was successfully deleted from repository \'" + repositoryId + "\'";

addActionMessage( msg );

reset();
// TODO cleanup facet which contains classifier information
return SUCCESS;
}


String path = repository.toMetadataPath( ref );
int index = path.lastIndexOf( '/' );
path = path.substring( 0, index );
File targetPath = new File( repoConfig.getLocation(), path );

if ( !targetPath.exists() )
{
throw new ContentNotFoundException( groupId + ":" + artifactId + ":" + version );
}

// TODO: this should be in the storage mechanism so that it is all tied together
// delete from file system
repository.deleteVersion( ref );

File metadataFile = getMetadata( targetPath.getAbsolutePath() );
ArchivaRepositoryMetadata metadata = getMetadata( metadataFile );

updateMetadata( metadata, metadataFile, lastUpdatedTimestamp );

MetadataRepository metadataRepository = repositorySession.getRepository();

Collection<ArtifactMetadata> artifacts =
metadataRepository.getArtifacts( repositoryId, groupId, artifactId, version );

for ( ArtifactMetadata artifact : artifacts )
{
// TODO: mismatch between artifact (snapshot) version and project (base) version here
if ( artifact.getVersion().equals( version ) )
{
metadataRepository.removeArtifact( artifact.getRepositoryId(), artifact.getNamespace(),
artifact.getProject(), artifact.getVersion(), artifact.getId() );

// TODO: move into the metadata repository proper - need to differentiate attachment of
// repository metadata to an artifact
for ( RepositoryListener listener : listeners )
{
listener.deleteArtifact( metadataRepository, repository.getId(), artifact.getNamespace(),
artifact.getProject(), artifact.getVersion(), artifact.getId() );
}

triggerAuditEvent( repositoryId, path, AuditEvent.REMOVE_FILE );
}
}
repositorySession.save();
}
catch ( ContentNotFoundException e )
{
addActionError( "Artifact does not exist: " + e.getMessage() );
return ERROR;
}
catch ( RepositoryNotFoundException e )
{
addActionError( "Target repository cannot be found: " + e.getMessage() );
return ERROR;
}
catch ( RepositoryException e )
{
addActionError( "Repository exception: " + e.getMessage() );
return ERROR;
}
catch ( MetadataResolutionException e )
{
addActionError( "Repository exception: " + e.getMessage() );
return ERROR;
}
catch ( MetadataRepositoryException e )
{
addActionError( "Repository exception: " + e.getMessage() );
return ERROR;
Artifact artifact = new Artifact();
artifact.setGroupId( groupId );
artifact.setArtifactId( artifactId );
artifact.setVersion( version );
artifact.setClassifier( classifier );
artifact.setPackaging( type );

repositoriesService.deleteArtifact( artifact, repositoryId );
}
catch ( RepositoryAdminException e )
catch ( ArchivaRestServiceException e )
{
addActionError( "RepositoryAdmin exception: " + e.getMessage() );
addActionError( "ArchivaRestServiceException exception: " + e.getMessage() );
return ERROR;
}
finally
{
repositorySession.close();
RedbackAuthenticationThreadLocal.set( null );
}

String msg = "Artifact \'" + groupId + ":" + artifactId + ":" + version
@@ -362,83 +231,6 @@ public class DeleteArtifactAction
return SUCCESS;
}

private File getMetadata( String targetPath )
{
String artifactPath = targetPath.substring( 0, targetPath.lastIndexOf( File.separatorChar ) );

return new File( artifactPath, MetadataTools.MAVEN_METADATA );
}

private ArchivaRepositoryMetadata getMetadata( File metadataFile )
throws RepositoryMetadataException
{
ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
if ( metadataFile.exists() )
{
metadata = RepositoryMetadataReader.read( metadataFile );
}
return metadata;
}

/**
* Update artifact level metadata. Creates one if metadata does not exist after artifact deletion.
*
* @param metadata
*/
private void updateMetadata( ArchivaRepositoryMetadata metadata, File metadataFile, Date lastUpdatedTimestamp )
throws RepositoryMetadataException
{
List<String> availableVersions = new ArrayList<String>();
String latestVersion = "";

if ( metadataFile.exists() )
{
if ( metadata.getAvailableVersions() != null )
{
availableVersions = metadata.getAvailableVersions();

if ( availableVersions.size() > 0 )
{
Collections.sort( availableVersions, VersionComparator.getInstance() );

if ( availableVersions.contains( version ) )
{
availableVersions.remove( availableVersions.indexOf( version ) );
}
if ( availableVersions.size() > 0 )
{
latestVersion = availableVersions.get( availableVersions.size() - 1 );
}
}
}
}

if ( metadata.getGroupId() == null )
{
metadata.setGroupId( groupId );
}
if ( metadata.getArtifactId() == null )
{
metadata.setArtifactId( artifactId );
}

if ( !VersionUtil.isSnapshot( version ) )
{
if ( metadata.getReleasedVersion() != null && metadata.getReleasedVersion().equals( version ) )
{
metadata.setReleasedVersion( latestVersion );
}
}

metadata.setLatestVersion( latestVersion );
metadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
metadata.setAvailableVersions( availableVersions );

RepositoryMetadataWriter.write( metadata, metadataFile );
ChecksummedFile checksum = new ChecksummedFile( metadataFile );
checksum.fixChecksums( algorithms );
}

public void validate()
{
try
@@ -511,23 +303,23 @@ public class DeleteArtifactAction
}
}

public List<RepositoryListener> getListeners()
public ManagedRepositoryAdmin getManagedRepositoryAdmin()
{
return listeners;
return managedRepositoryAdmin;
}

public void setRepositoryFactory( RepositoryContentFactory repositoryFactory )
public void setManagedRepositoryAdmin( ManagedRepositoryAdmin managedRepositoryAdmin )
{
this.repositoryFactory = repositoryFactory;
this.managedRepositoryAdmin = managedRepositoryAdmin;
}

public ManagedRepositoryAdmin getManagedRepositoryAdmin()
public RepositoriesService getRepositoriesService()
{
return managedRepositoryAdmin;
return repositoriesService;
}

public void setManagedRepositoryAdmin( ManagedRepositoryAdmin managedRepositoryAdmin )
public void setRepositoriesService( RepositoriesService repositoriesService )
{
this.managedRepositoryAdmin = managedRepositoryAdmin;
this.repositoriesService = repositoriesService;
}
}

+ 20
- 16
archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/archiva/web/action/DeleteArtifactActionTest.java Ver fichero

@@ -22,25 +22,32 @@ package org.apache.archiva.web.action;
import net.sf.beanlib.provider.replicator.BeanReplicator;
import org.apache.archiva.admin.model.beans.ManagedRepository;
import org.apache.archiva.admin.repository.managed.DefaultManagedRepositoryAdmin;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.webtest.memory.TestRepositorySessionFactory;
import org.apache.commons.lang.StringUtils;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.Configuration;
import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.RepositoryContentFactory;
import org.apache.archiva.repository.content.ManagedDefaultRepositoryContent;
import org.apache.archiva.rest.services.DefaultRepositoriesService;
import org.apache.archiva.webtest.memory.TestRepositorySessionFactory;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.StrutsSpringTestCase;
import org.codehaus.plexus.redback.users.User;
import org.codehaus.redback.rest.services.RedbackAuthenticationThreadLocal;
import org.codehaus.redback.rest.services.RedbackRequestInformation;
import org.easymock.MockControl;
import org.easymock.classextension.MockClassControl;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.when;

public class DeleteArtifactActionTest
@@ -82,8 +89,8 @@ public class DeleteArtifactActionTest
{
super.setUp();

//action = (DeleteArtifactAction) lookup( Action.class.getName(), "deleteArtifactAction" );
action = (DeleteArtifactAction) getActionProxy( "/deleteArtifact.action" ).getAction();
action.setPrincipal( "admin" );
assertNotNull( action );

configurationControl = MockControl.createControl( ArchivaConfiguration.class );
@@ -103,8 +110,9 @@ public class DeleteArtifactActionTest

repositorySessionFactory.setRepositorySession( repositorySession );

(( DefaultManagedRepositoryAdmin)action.getManagedRepositoryAdmin()).setArchivaConfiguration( configuration );
action.setRepositoryFactory( repositoryFactory );
( (DefaultManagedRepositoryAdmin) ( (DefaultRepositoriesService) action.getRepositoriesService() ).getManagedRepositoryAdmin() ).setArchivaConfiguration(
configuration );
( (DefaultRepositoriesService) action.getRepositoriesService() ).setRepositoryFactory( repositoryFactory );
}

@Override
@@ -116,12 +124,6 @@ public class DeleteArtifactActionTest
super.tearDown();
}

public void testGetListeners()
throws Exception
{
assertNotNull( action.getListeners() );
assertFalse( action.getListeners().isEmpty() );
}

public void testNPEInDeleteArtifact()
throws Exception
@@ -151,8 +153,10 @@ public class DeleteArtifactActionTest

action.doDelete();

String artifactPath = REPO_LOCATION + "/" + StringUtils.replace( GROUP_ID, ".", "/" ) + "/"
+ StringUtils.replace( ARTIFACT_ID, ".", "/" ) + "/" + VERSION + "/" + ARTIFACT_ID + "-" + VERSION;
String artifactPath =
REPO_LOCATION + "/" + StringUtils.replace( GROUP_ID, ".", "/" ) + "/" + StringUtils.replace( ARTIFACT_ID,
".", "/" )
+ "/" + VERSION + "/" + ARTIFACT_ID + "-" + VERSION;

assertFalse( new File( artifactPath + ".jar" ).exists() );
assertFalse( new File( artifactPath + ".jar.sha1" ).exists() );

Cargando…
Cancelar
Guardar