Bläddra i källkod

Adding task admin implementation

pull/62/head
Martin Stockhammer 3 år sedan
förälder
incheckning
b32d75a85b
26 ändrade filer med 1420 tillägg och 108 borttagningar
  1. 13
    2
      archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/AbstractArtifactConsumerTest.java
  2. 8
    2
      archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/AbstractRepositoryPurgeTest.java
  3. 1
    1
      archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/resources/spring-context-cleanup-released-snapshots.xml
  4. 1
    0
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/admin/ArchivaAdministration.java
  5. 115
    0
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/admin/RepositoryTaskAdministration.java
  6. 87
    0
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/IndexingTask.java
  7. 84
    0
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/MetadataScanTask.java
  8. 121
    0
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/RepositoryTaskInfo.java
  9. 85
    0
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/ScanStatus.java
  10. 4
    0
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/resources/org/apache/archiva/admin/model/error/AdminErrors.properties
  11. 17
    0
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/pom.xml
  12. 360
    0
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/admin/DefaultRepositoryTaskAdministration.java
  13. 1
    1
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/mock/MockRepositoryArchivaTaskScheduler.java
  14. 267
    0
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/admin/RepositoryTaskAdministrationTest.java
  15. 2
    1
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/resources/spring-context.xml
  16. 6
    6
      archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/IndexingTask.java
  17. 10
    2
      archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/Repository.java
  18. 12
    23
      archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanStatus.java
  19. 5
    4
      archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanTask.java
  20. 1
    1
      archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/ErrorKeys.java
  21. 0
    4
      archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryService.java
  22. 1
    0
      archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultMavenManagedRepositoryService.java
  23. 1
    0
      archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryGroupService.java
  24. 53
    59
      archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryService.java
  25. 3
    2
      archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultSecurityConfigurationService.java
  26. 162
    0
      archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/v2/NativeRepositoryServiceTest.java

+ 13
- 2
archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/AbstractArtifactConsumerTest.java Visa fil

@@ -25,8 +25,10 @@ import org.apache.archiva.configuration.FileType;
import org.apache.archiva.configuration.FileTypes;
import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
import org.apache.archiva.consumers.functors.ConsumerWantsFilePredicate;
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.apache.commons.lang3.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -37,8 +39,7 @@ import javax.inject.Inject;
import java.nio.file.Path;
import java.nio.file.Paths;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.*;

@RunWith( ArchivaSpringJUnit4ClassRunner.class )
@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } )
@@ -54,6 +55,8 @@ public abstract class AbstractArtifactConsumerTest
@Inject
ArchivaConfiguration archivaConfiguration;

ArchivaRepositoryRegistry repositoryRegistry;


@Before
public void setUp()
@@ -68,6 +71,14 @@ public abstract class AbstractArtifactConsumerTest
archivaConfiguration.getConfiguration().getArchivaRuntimeConfiguration().addChecksumType("SHA256");

repoLocation = Paths.get( "target/test-" + getName() + "/test-repo" );

repositoryRegistry = applicationContext.getBean( "repositoryRegistry", ArchivaRepositoryRegistry.class );
assertNotNull( repositoryRegistry );
}

@After
public void destroy() {
repositoryRegistry.destroy();
}



+ 8
- 2
archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/AbstractRepositoryPurgeTest.java Visa fil

@@ -24,6 +24,8 @@ import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.metadata.repository.RepositorySessionFactory;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
import org.apache.archiva.repository.maven.metadata.storage.Maven2RepositoryPathTranslator;
import org.apache.archiva.repository.base.BasicManagedRepository;
import org.apache.archiva.repository.ReleaseScheme;
@@ -53,8 +55,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;

/**
@@ -108,6 +109,8 @@ public abstract class AbstractRepositoryPurgeTest

protected MetadataRepository metadataRepository;

protected ArchivaRepositoryRegistry repositoryRegistry;

@Inject
protected ApplicationContext applicationContext;

@@ -127,6 +130,8 @@ public abstract class AbstractRepositoryPurgeTest
repositorySession = sessionControl.createMock( RepositorySession.class );
metadataRepository = mock( MetadataRepository.class );
sessionFactory = sessionFactoryControl.createMock( RepositorySessionFactory.class );
repositoryRegistry = applicationContext.getBean( "repositoryRegistry", ArchivaRepositoryRegistry.class );
assertNotNull( repositoryRegistry );
EasyMock.expect( repositorySession.getRepository() ).andStubReturn( metadataRepository );
EasyMock.expect( sessionFactory.createSession( ) ).andStubReturn( repositorySession );

@@ -138,6 +143,7 @@ public abstract class AbstractRepositoryPurgeTest
{
config = null;
repo = null;
repositoryRegistry.destroy();

}


+ 1
- 1
archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/resources/spring-context-cleanup-released-snapshots.xml Visa fil

@@ -32,7 +32,7 @@
</bean>
<alias name="archivaConfiguration#cleanup-released-snapshots" alias="archivaConfiguration"/>
<alias name="archivaConfiguration#cleanup-released-snapshots" alias="archivaConfiguration#default"/>
<context:component-scan base-package="org.apache.archiva.configuration,org.apache.archiva.repository.content.maven2,org.apache.archiva.indexer.maven"/>
<context:component-scan base-package="org.apache.archiva.configuration,org.apache.archiva.repository.content.base,org.apache.archiva.indexer.maven"/>

<alias name="repositoryContentFactory#cleanup-released-snapshots" alias="repositoryContentFactory#default" />


+ 1
- 0
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/admin/ArchivaAdministration.java Visa fil

@@ -29,6 +29,7 @@ import org.apache.archiva.admin.model.beans.UiConfiguration;
import java.util.List;

/**
* Base administration interface for Archiva. Provides methods for managing archiva base tasks.
* @author Olivier Lamy
* @since 1.4-M1
*/

+ 115
- 0
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/admin/RepositoryTaskAdministration.java Visa fil

@@ -0,0 +1,115 @@
package org.apache.archiva.admin.model.admin;
/*
* 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.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.beans.RepositoryTaskInfo;
import org.apache.archiva.admin.model.beans.ScanStatus;
import org.springframework.util.StopWatch;

import java.util.List;

/**
* Interface for managing repository scan tasks.
*
* @author Martin Stockhammer <martin_s@apache.org>
* @since 3.0
*/
public interface RepositoryTaskAdministration
{
/**
* Schedules a full repository scan for the given repository. Metadata and Index are updated.
* All files are scanned, even if they were not modified since the last scan.
*
* @param repositoryId the repository identifier
* @throws RepositoryAdminException if it was not possible to schedule the scan
*/
void scheduleFullScan( String repositoryId ) throws RepositoryAdminException;

/**
* Schedules a scan that rebuilds the fulltext index of the repository.
*
* @param repositoryId the repository identifier
* @throws RepositoryAdminException if it was not possible to schedule the index scan
*/
void scheduleIndexFullScan( String repositoryId ) throws RepositoryAdminException;

/**
* Schedules a scan that rebuilds the fulltext index of the repository.
*
* @param repositoryId the repository identifier
* @param relativePath the path to the file to add to the index
* @throws RepositoryAdminException if it was not possible to schedule the index scan
*/
void scheduleIndexScan( String repositoryId, String relativePath ) throws RepositoryAdminException;

/**
* Schedules a scan that rebuilds metadata of the repository
*
* @param repositoryId the repository identifier
* @throws RepositoryAdminException if it was not possible to schedule the index scan
*/
void scheduleMetadataFullScan( String repositoryId ) throws RepositoryAdminException;

/**
* Schedules a scan that rebuilds metadata of the repository but only for updated files.
*
* @param repositoryId the repository identifier
* @throws RepositoryAdminException if it was not possible to schedule the index scan
*/
void scheduleMetadataUpdateScan( String repositoryId ) throws RepositoryAdminException;

/**
* Returns information about currently running scans for the given repository.
*
* @return the status information
* @param repositoryId the repository identifier
* @throws RepositoryAdminException if there was an error retrieving the scan status
*/
ScanStatus getCurrentScanStatus(String repositoryId) throws RepositoryAdminException;


/**
* Returns information about currently running scans for all repositories.
*
* @return the status information
* @throws RepositoryAdminException if there was an error retrieving the scan status
*/
ScanStatus getCurrentScanStatus() throws RepositoryAdminException;

/**
* Cancels the tasks either running or queued for the given repository.
* @param repositoryId the repository identifier
* @return a list of canceled tasks.
*/
List<RepositoryTaskInfo> cancelTasks(String repositoryId) throws RepositoryAdminException;

/**
* Cancels the metadata scan tasks either running or queued for the given repository.
* @param repositoryId the repository identifier
* @return a list of canceled tasks.
*/
List<RepositoryTaskInfo> cancelScanTasks(String repositoryId) throws RepositoryAdminException;

/**
* Cancels the indexing tasks either running or queued for the given repository.
* @param repositoryId the repository identifier
* @return a list of canceled tasks.
*/
List<RepositoryTaskInfo> cancelIndexTasks(String repositoryId) throws RepositoryAdminException;
}

+ 87
- 0
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/IndexingTask.java Visa fil

@@ -0,0 +1,87 @@
package org.apache.archiva.admin.model.beans;
/*
* 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.io.Serializable;

/**
* Information about index update tasks running on a repository.
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class IndexingTask extends RepositoryTaskInfo implements Serializable
{
private static final long serialVersionUID = -1947200162602613310L;
/**
* <code>true</code>, if this task is just updating the existing index.
*/
private boolean updateOnly;

public boolean isUpdateOnly( )
{
return updateOnly;
}

public void setUpdateOnly( boolean updateOnly )
{
this.updateOnly = updateOnly;
}

@Override
public boolean equals( Object o )
{
if ( this == o ) return true;
if ( o == null || getClass( ) != o.getClass( ) ) return false;

IndexingTask that = (IndexingTask) o;

if ( isFullScan( ) != that.fullScan ) return false;
if ( updateOnly != that.updateOnly ) return false;
if ( isRunning( ) != that.isRunning( ) ) return false;
if ( getMaxExecutionTimeMs( ) != that.getMaxExecutionTimeMs( ) ) return false;
if ( !getRepositoryId( ).equals( that.getRepositoryId( ) ) ) return false;
return getResource( ).equals( that.getResource( ) );
}

@Override
public int hashCode( )
{
int result = getRepositoryId( ).hashCode( );
result = 31 * result + ( isFullScan( ) ? 1 : 0 );
result = 31 * result + ( updateOnly ? 1 : 0 );
result = 31 * result + getResource( ).hashCode( );
result = 31 * result + ( isRunning( ) ? 1 : 0 );
result = 31 * result + (int) ( getMaxExecutionTimeMs( ) ^ ( getMaxExecutionTimeMs( ) >>> 32 ) );
return result;
}

@Override
public String toString( )
{
final StringBuilder sb = new StringBuilder( "IndexingTask{" );
sb.append( "repositoryId='" ).append( getRepositoryId( ) ).append( '\'' );
sb.append( ", fullRepository=" ).append( isFullScan( ) );
sb.append( ", updateOnly=" ).append( updateOnly );
sb.append( ", resource='" ).append( getResource( ) ).append( '\'' );
sb.append( ", running=" ).append( isRunning( ) );
sb.append( ", maxExecutionTimeMs=" ).append( getMaxExecutionTimeMs( ) );
sb.append( '}' );
return sb.toString( );
}

}

+ 84
- 0
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/MetadataScanTask.java Visa fil

@@ -0,0 +1,84 @@
package org.apache.archiva.admin.model.beans;
/*
* 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.io.Serializable;

/**
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class MetadataScanTask extends RepositoryTaskInfo implements Serializable
{
private static final long serialVersionUID = -681163357370848098L;
/**
* <code>true</code> if related artifacts are updated too.
*/
private boolean updateRelatedArtifacts;

public boolean isUpdateRelatedArtifacts( )
{
return updateRelatedArtifacts;
}

public void setUpdateRelatedArtifacts( boolean updateRelatedArtifacts )
{
this.updateRelatedArtifacts = updateRelatedArtifacts;
}

@Override
public boolean equals( Object o )
{
if ( this == o ) return true;
if ( o == null || getClass( ) != o.getClass( ) ) return false;

MetadataScanTask scanTask = (MetadataScanTask) o;

if ( updateRelatedArtifacts != scanTask.updateRelatedArtifacts ) return false;
if ( fullScan != scanTask.fullScan ) return false;
if ( running != scanTask.running ) return false;
if ( maxExecutionTimeMs != scanTask.maxExecutionTimeMs ) return false;
if ( !repositoryId.equals( scanTask.repositoryId ) ) return false;
return resource.equals( scanTask.resource );
}

@Override
public int hashCode( )
{
int result = repositoryId.hashCode( );
result = 31 * result + ( updateRelatedArtifacts ? 1 : 0 );
result = 31 * result + ( fullScan ? 1 : 0 );
result = 31 * result + ( running ? 1 : 0 );
result = 31 * result + resource.hashCode( );
result = 31 * result + (int) ( maxExecutionTimeMs ^ ( maxExecutionTimeMs >>> 32 ) );
return result;
}

@Override
public String toString( )
{
final StringBuilder sb = new StringBuilder( "ScanTask{" );
sb.append( "repositoryId='" ).append( repositoryId ).append( '\'' );
sb.append( ", updateRelatedArtifacts=" ).append( updateRelatedArtifacts );
sb.append( ", fullRepository=" ).append( fullScan );
sb.append( ", running=" ).append( running );
sb.append( ", resource='" ).append( resource ).append( '\'' );
sb.append( ", maxExecutionTimeMs=" ).append( maxExecutionTimeMs );
sb.append( '}' );
return sb.toString( );
}
}

+ 121
- 0
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/RepositoryTaskInfo.java Visa fil

@@ -0,0 +1,121 @@
package org.apache.archiva.admin.model.beans;
/*
* 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.time.OffsetDateTime;

/**
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class RepositoryTaskInfo
{
/**
* The repository identifier
*/
protected String repositoryId = "";
/**
* <code>true</code>, if all files are scanned. <code>false</code>, if only updated files are scanned
*/
protected boolean fullScan;
/**
* The scanned resource, if this is not a full repository scan
*/
protected String resource = "";
/**
* Running status of the task.
*/
protected boolean running = false;
/**
* The maximum execution time set for this task.
*/
protected long maxExecutionTimeMs = 0;
/**
* The time when the status check was built
*/
OffsetDateTime checkTime;

public RepositoryTaskInfo( )
{
this.checkTime = OffsetDateTime.now( );
}

public RepositoryTaskInfo( OffsetDateTime checkTime )
{
this.checkTime = checkTime;
}

public String getRepositoryId( )
{
return repositoryId;
}

public void setRepositoryId( String repositoryId )
{
this.repositoryId = repositoryId==null?"":repositoryId;
}

public boolean isFullScan( )
{
return fullScan;
}

public void setFullScan( boolean fullScan )
{
this.fullScan = fullScan;
}

public String getResource( )
{
return resource;
}

public void setResource( String resource )
{
this.resource = resource == null ? "" : resource;
}

public boolean isRunning( )
{
return running;
}

public void setRunning( boolean running )
{
this.running = running;
}

public long getMaxExecutionTimeMs( )
{
return maxExecutionTimeMs;
}

public void setMaxExecutionTimeMs( long maxExecutionTimeMs )
{
this.maxExecutionTimeMs = maxExecutionTimeMs;
}

public OffsetDateTime getCheckTime( )
{
return checkTime;
}

public void setCheckTime( OffsetDateTime checkTime )
{
this.checkTime = checkTime;
}
}

+ 85
- 0
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/ScanStatus.java Visa fil

@@ -0,0 +1,85 @@
package org.apache.archiva.admin.model.beans;
/*
* 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.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
* Information about running and queued repository scans.
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class ScanStatus implements Serializable
{
private List<IndexingTask> indexingQueue = new ArrayList<>( );
private List<MetadataScanTask> scanQueue = new ArrayList<>( );

public ScanStatus( )
{
}

public boolean isMetadataScanRunning( )
{
return scanQueue.size( ) > 0 && scanQueue.get(0).isRunning();
}

public int getMetadataScanQueueSize() {
int size= scanQueue.size( );
if (size>0) {
return size-1;
} else {
return 0;
}
}

public boolean isIndexScanRunning( )
{
return indexingQueue.size()>0 && indexingQueue.get(0).isRunning();
}

public int getIndexScanQueueSize() {
int size = indexingQueue.size();
if (size>0) {
return size-1;
} else {
return 0;
}
}

public List<IndexingTask> getIndexingQueue( )
{
return indexingQueue;
}

public void setIndexingQueue( List<IndexingTask> indexingQueue )
{
this.indexingQueue = new ArrayList<>( indexingQueue );
}

public List<MetadataScanTask> getScanQueue( )
{
return scanQueue;
}

public void setScanQueue( List<MetadataScanTask> scanQueue )
{
this.scanQueue = new ArrayList<>( scanQueue );
}
}

+ 4
- 0
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/resources/org/apache/archiva/admin/model/error/AdminErrors.properties Visa fil

@@ -26,3 +26,7 @@ repository_group.repository.not_found=The member repository with id "{0}" does n
repository_group.registry.add_error=The registry could not add the repository "{0}": {1}
repository_group.registry.update_error=The registry could not update the repository "{0}": {1}
repository_group.not_editable=The repository group "{0}" is not editable
repository.id.invalid=The given repository id {0} is not valid.
repository.not_found=The repository with the given id "{0}" was not found
repository.file.not_found=No file "{1}" found in the repository "{0}"
repository.scan.task_retrieval_failed=Could not get scan task information: {0}

+ 17
- 0
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/pom.xml Visa fil

@@ -117,6 +117,18 @@
<groupId>org.apache.archiva.components</groupId>
<artifactId>archiva-components-spring-taskqueue</artifactId>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-scheduler-indexing</artifactId>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-scheduler-repository</artifactId>
</dependency>
<dependency>
<groupId>org.apache.archiva.maven</groupId>
<artifactId>archiva-maven-scheduler</artifactId>
</dependency>


<dependency>
@@ -166,6 +178,11 @@


<!-- Test scope -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-proxy</artifactId>

+ 360
- 0
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/admin/DefaultRepositoryTaskAdministration.java Visa fil

@@ -0,0 +1,360 @@
package org.apache.archiva.admin.repository.admin;
/*
* 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.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.admin.RepositoryTaskAdministration;
import org.apache.archiva.admin.model.beans.IndexingTask;
import org.apache.archiva.admin.model.beans.MetadataScanTask;
import org.apache.archiva.admin.model.beans.RepositoryTaskInfo;
import org.apache.archiva.admin.model.beans.ScanStatus;
import org.apache.archiva.components.taskqueue.TaskQueueException;
import org.apache.archiva.components.taskqueue.execution.TaskQueueExecutor;
import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
import org.apache.archiva.scheduler.indexing.IndexingArchivaTaskScheduler;
import org.apache.archiva.scheduler.repository.model.RepositoryArchivaTaskScheduler;
import org.apache.archiva.scheduler.repository.model.RepositoryTask;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.inject.Named;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author Martin Stockhammer <martin_s@apache.org>
*/
@Service( "repositoryTaskAdministration#default" )
public class DefaultRepositoryTaskAdministration implements RepositoryTaskAdministration
{
private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryTaskAdministration.class );


final RepositoryRegistry repositoryRegistry;

final
TaskQueueExecutor<ArtifactIndexingTask> indexingTaskExecutor;

final
TaskQueueExecutor<RepositoryTask> scanningTaskExecutor;

private final RepositoryArchivaTaskScheduler repositoryArchivaTaskScheduler;

private final IndexingArchivaTaskScheduler indexingArchivaTaskScheduler;

public DefaultRepositoryTaskAdministration( RepositoryRegistry repositoryRegistry,
@Named( value = "taskQueueExecutor#indexing" ) TaskQueueExecutor<ArtifactIndexingTask> indexingTaskExecutor,
@Named( value = "taskQueueExecutor#repository-scanning" ) TaskQueueExecutor<RepositoryTask> scanningTaskExecutor,
@Named( value = "archivaTaskScheduler#repository" ) RepositoryArchivaTaskScheduler repositoryArchivaTaskScheduler,
@Named( value = "archivaTaskScheduler#indexing" ) IndexingArchivaTaskScheduler indexingArchivaTaskScheduler)
{
this.repositoryRegistry = repositoryRegistry;
this.indexingTaskExecutor = indexingTaskExecutor;
this.scanningTaskExecutor = scanningTaskExecutor;
this.repositoryArchivaTaskScheduler = repositoryArchivaTaskScheduler;
this.indexingArchivaTaskScheduler = indexingArchivaTaskScheduler;
}

@Override
public void scheduleFullScan( String repositoryId ) throws RepositoryAdminException
{
if ( StringUtils.isEmpty( repositoryId ) ) {
throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
}
try
{
org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
if (repository==null) {
throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
}
ArtifactIndexingTask task =
new ArtifactIndexingTask( repository, null, ArtifactIndexingTask.Action.FINISH, repository.getIndexingContext( ) );
task.setExecuteOnEntireRepo( true );
task.setOnlyUpdate( false );
indexingArchivaTaskScheduler.queueTask( task );
repositoryArchivaTaskScheduler.queueTask( new RepositoryTask( repositoryId, true ) );
}
catch ( TaskQueueException e )
{
log.error( "Could not queue the task: {}", e.getMessage( ), e );
throw RepositoryAdminException.ofKey( "repository.scan.task_queue_error", e, e.getMessage( ) );
}
}

@Override
public void scheduleIndexFullScan( String repositoryId ) throws RepositoryAdminException
{
if ( StringUtils.isEmpty( repositoryId ) ) {
throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
}
try
{
org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
if (repository==null) {
throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
}
ArtifactIndexingTask task =
new ArtifactIndexingTask( repository, null, ArtifactIndexingTask.Action.FINISH, repository.getIndexingContext( ) );
task.setExecuteOnEntireRepo( true );
task.setOnlyUpdate( false );
indexingArchivaTaskScheduler.queueTask( task );
}
catch ( TaskQueueException e )
{
log.error( "Could not queue the task: {}", e.getMessage( ), e );
throw RepositoryAdminException.ofKey( "repository.scan.task_queue_error", e, e.getMessage( ) );
}
}

@Override
public void scheduleIndexScan( String repositoryId, String relativePath ) throws RepositoryAdminException
{
if ( StringUtils.isEmpty( repositoryId ) ) {
throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
}
try
{
org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
if (repository==null) {
throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
}
StorageAsset asset = repository.getAsset( relativePath );
if (!asset.exists()) {
throw RepositoryAdminException.ofKey( "repository.file.not_found", repositoryId, relativePath );
}
ArtifactIndexingTask task =
new ArtifactIndexingTask( repository, asset.getFilePath( ), ArtifactIndexingTask.Action.FINISH, repository.getIndexingContext( ) );
task.setExecuteOnEntireRepo( false );
task.setOnlyUpdate( true );
indexingArchivaTaskScheduler.queueTask( task );
}
catch ( TaskQueueException e )
{
log.error( "Could not queue the task: {}", e.getMessage( ), e );
throw RepositoryAdminException.ofKey( "repository.scan.task_queue_error", e, e.getMessage( ) );
}

}

@Override
public void scheduleMetadataFullScan( String repositoryId ) throws RepositoryAdminException
{
if ( StringUtils.isEmpty( repositoryId ) ) {
throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
}
try
{
org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
if (repository==null) {
throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
}
repositoryArchivaTaskScheduler.queueTask( new RepositoryTask( repositoryId, true ) );
}
catch ( TaskQueueException e )
{
log.error( "Could not queue the task: {}", e.getMessage( ), e );
throw RepositoryAdminException.ofKey( "repository.scan.task_queue_error", e, e.getMessage( ) );
}

}

@Override
public void scheduleMetadataUpdateScan( String repositoryId ) throws RepositoryAdminException
{
if ( StringUtils.isEmpty( repositoryId ) ) {
throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
}
try
{
org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
if (repository==null) {
throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
}
repositoryArchivaTaskScheduler.queueTask( new RepositoryTask( repositoryId, false ) );
}
catch ( TaskQueueException e )
{
log.error( "Could not queue the task: {}", e.getMessage( ), e );
throw RepositoryAdminException.ofKey( "repository.scan.task_queue_error", e, e.getMessage( ) );
}
}

public static MetadataScanTask getMetadataScanTaskInfo(RepositoryTask repositoryTask) {
MetadataScanTask scanTask = new MetadataScanTask( );
scanTask.setFullScan( repositoryTask.isScanAll());
scanTask.setUpdateRelatedArtifacts( repositoryTask.isUpdateRelatedArtifacts() );
StorageAsset file = repositoryTask.getResourceFile( );
scanTask.setResource( repositoryTask.getResourceFile( )==null?"":repositoryTask.getResourceFile().toString( ) );
scanTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTime() );
scanTask.setRepositoryId( repositoryTask.getRepositoryId( ) );
return scanTask;
}

public static IndexingTask getIndexingTaskInfo(ArtifactIndexingTask repositoryTask) {
IndexingTask indexingTask = new IndexingTask( );
indexingTask.setFullScan( repositoryTask.isExecuteOnEntireRepo());
indexingTask.setUpdateOnly( repositoryTask.isOnlyUpdate() );
indexingTask.setResource( repositoryTask.getResourceFile( )==null?"":repositoryTask.getResourceFile().toString( ) );
indexingTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTime() );
indexingTask.setRepositoryId( repositoryTask.getRepository().getId() );
return indexingTask;

}

public void updateScanInfo( ScanStatus scanStatus, RepositoryTask runningRepositoryTask, List<RepositoryTask> taskQueue) {
List<MetadataScanTask> newScanQueue = new ArrayList<>( );
if (runningRepositoryTask!=null) {
MetadataScanTask taskInfo = getMetadataScanTaskInfo( runningRepositoryTask );
taskInfo.setRunning( true );
newScanQueue.add( 0, taskInfo);
}
newScanQueue.addAll( taskQueue.stream( ).map( task -> getMetadataScanTaskInfo( task ) ).collect( Collectors.toList( ) ) );
scanStatus.setScanQueue( newScanQueue );
}

public void updateIndexInfo( ScanStatus scanStatus, ArtifactIndexingTask runningIndexingTask, List<ArtifactIndexingTask> taskQueue) {
List<IndexingTask> newIndexQueue = new ArrayList<>( );
if (runningIndexingTask!=null) {
IndexingTask taskInfo = getIndexingTaskInfo( runningIndexingTask );
taskInfo.setRunning( true );
newIndexQueue.add(taskInfo );
}
newIndexQueue.addAll( taskQueue.stream( ).map( task -> getIndexingTaskInfo( task ) ).collect( Collectors.toList( ) ) );
scanStatus.setIndexingQueue( newIndexQueue );
}


@Override
public ScanStatus getCurrentScanStatus( String repositoryId ) throws RepositoryAdminException
{
if ( StringUtils.isEmpty( repositoryId ) ) {
throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
}
org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
if (repository==null) {
throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
}
ScanStatus status = new ScanStatus( );
try
{
RepositoryTask scanTask = scanningTaskExecutor.getCurrentTask( );
if ( scanTask!=null && !repositoryId.equals( scanTask.getRepositoryId( ) ) )
{
scanTask = null;
}
ArtifactIndexingTask indexTask = indexingTaskExecutor.getCurrentTask( );
if ( indexTask!=null && !repositoryId.equals( indexTask.getRepository( ).getId( ) ) )
{
indexTask = null;
}
updateScanInfo( status, scanTask, scanningTaskExecutor.getQueue( ).getQueueSnapshot( ).stream( ).filter( task -> repositoryId.equals( task.getRepositoryId( ) ) ).collect( Collectors.toList( ) ) );
updateIndexInfo( status, indexTask, indexingTaskExecutor.getQueue( ).getQueueSnapshot( ).stream( ).filter( task -> repositoryId.equals( task.getRepository( ).getId( ) ) ).collect( Collectors.toList( ) ) );
return status;
}
catch ( TaskQueueException e )
{
log.error( "Could not get task information: {}", e.getMessage( ), e );
throw RepositoryAdminException.ofKey( "repository.scan.task_retrieval_failed", e.getMessage( ) );
}

}

@Override
public ScanStatus getCurrentScanStatus( ) throws RepositoryAdminException
{
ScanStatus status = new ScanStatus( );
try
{
RepositoryTask scanTask = scanningTaskExecutor.getCurrentTask( );
ArtifactIndexingTask indexTask = indexingTaskExecutor.getCurrentTask( );
updateScanInfo( status, scanTask, scanningTaskExecutor.getQueue( ).getQueueSnapshot() );
updateIndexInfo( status, indexTask, indexingTaskExecutor.getQueue( ).getQueueSnapshot( ) );
return status;
}
catch ( TaskQueueException e )
{
log.error( "Could not get task information: {}", e.getMessage( ), e );
throw RepositoryAdminException.ofKey( "repository.scan.task_retrieval_failed", e.getMessage( ) );
}

}

@Override
public List<RepositoryTaskInfo> cancelTasks( String repositoryId ) throws RepositoryAdminException
{
ArrayList<RepositoryTaskInfo> resultList = new ArrayList<>( );
resultList.addAll( cancelScanTasks( repositoryId ) );
resultList.addAll( cancelIndexTasks( repositoryId ) );
return resultList;
}

@Override
public List<RepositoryTaskInfo> cancelScanTasks( String repositoryId ) throws RepositoryAdminException
{
try
{
ArrayList<RepositoryTaskInfo> resultList = new ArrayList<>( );
List<RepositoryTask> removeTasks = scanningTaskExecutor.getQueue( ).getQueueSnapshot( ).stream( ).filter( task -> repositoryId.equals( task.getRepositoryId() ) ).collect( Collectors.toList( ) );
scanningTaskExecutor.getQueue( ).removeAll( removeTasks );
RepositoryTask currentTask = scanningTaskExecutor.getCurrentTask( );
if ( currentTask != null && repositoryId.equals( currentTask.getRepositoryId()) )
{
scanningTaskExecutor.cancelTask( currentTask );
resultList.add( getMetadataScanTaskInfo( currentTask ) );
}
resultList.addAll( removeTasks.stream( ).map( task -> getMetadataScanTaskInfo( task ) ).collect( Collectors.toList( ) ) );
return resultList;
}
catch ( TaskQueueException e )
{
throw RepositoryAdminException.ofKey( "repository.task.dequeue_failed", repositoryId );
}
}

@Override
public List<RepositoryTaskInfo> cancelIndexTasks( String repositoryId ) throws RepositoryAdminException
{
try
{
ArrayList<RepositoryTaskInfo> resultList = new ArrayList<>( );
List<ArtifactIndexingTask> removeTasks = indexingTaskExecutor.getQueue( ).getQueueSnapshot( ).stream( ).filter( task -> repositoryId.equals( task.getRepository( ).getId( ) ) ).collect( Collectors.toList( ) );
indexingTaskExecutor.getQueue( ).removeAll( removeTasks );
ArtifactIndexingTask currentTask = indexingTaskExecutor.getCurrentTask( );
if ( currentTask != null && repositoryId.equals( currentTask.getRepository( ).getId( ) ) )
{
indexingTaskExecutor.cancelTask( currentTask );
resultList.add( getIndexingTaskInfo( currentTask ) );
}
resultList.addAll( removeTasks.stream( ).map( task -> getIndexingTaskInfo( task ) ).collect( Collectors.toList( ) ) );
return resultList;
}
catch ( TaskQueueException e )
{
throw RepositoryAdminException.ofKey( "repository.task.dequeue_failed", repositoryId );
}
}


}

+ 1
- 1
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/mock/MockRepositoryArchivaTaskScheduler.java Visa fil

@@ -26,7 +26,7 @@ import org.springframework.stereotype.Service;
/**
* @author Olivier Lamy
*/
@Service("archivaTaskScheduler#repository")
@Service("archivaTaskScheduler#mock")
public class MockRepositoryArchivaTaskScheduler
implements RepositoryArchivaTaskScheduler
{

+ 267
- 0
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/admin/RepositoryTaskAdministrationTest.java Visa fil

@@ -0,0 +1,267 @@
package org.apache.archiva.admin.repository.admin;
/*
* 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.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.admin.RepositoryTaskAdministration;
import org.apache.archiva.admin.model.beans.ScanStatus;
import org.apache.archiva.components.taskqueue.TaskQueue;
import org.apache.archiva.components.taskqueue.TaskQueueException;
import org.apache.archiva.components.taskqueue.execution.TaskQueueExecutor;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
import org.apache.archiva.scheduler.indexing.IndexingArchivaTaskScheduler;
import org.apache.archiva.scheduler.repository.model.RepositoryArchivaTaskScheduler;
import org.apache.archiva.scheduler.repository.model.RepositoryTask;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

/**
* @author Martin Stockhammer <martin_s@apache.org>
*/
@Tag( "archiva-admin" )
@DisplayName( "Unit Tests for RepositoryTaskAdministration" )
public class RepositoryTaskAdministrationTest
{

private RepositoryTaskAdministration taskAdministration;
private TaskQueueExecutor<ArtifactIndexingTask> indexingTaskExecutor;
private TaskQueueExecutor<RepositoryTask> scanningTaskExecutor;
private RepositoryArchivaTaskScheduler repositoryArchivaTaskScheduler;
private IndexingArchivaTaskScheduler indexingArchivaTaskScheduler;
private RepositoryRegistry registry;

@BeforeEach
public void init() {
registry = mock( RepositoryRegistry.class );
indexingTaskExecutor = mock( TaskQueueExecutor.class );
scanningTaskExecutor = mock( TaskQueueExecutor.class );
repositoryArchivaTaskScheduler = mock( RepositoryArchivaTaskScheduler.class );
indexingArchivaTaskScheduler = mock( IndexingArchivaTaskScheduler.class );
this.taskAdministration = new DefaultRepositoryTaskAdministration( registry, indexingTaskExecutor,
scanningTaskExecutor, repositoryArchivaTaskScheduler, indexingArchivaTaskScheduler );
}

@Test
public void testScanStatus() throws RepositoryAdminException, TaskQueueException
{
TaskQueue queue = mock( TaskQueue.class );
TaskQueue indexQueue = mock( TaskQueue.class );

List<RepositoryTask> scanList = new ArrayList<>( );
RepositoryTask scanTask1 = new RepositoryTask( );
scanTask1.setRepositoryId( "abcde" );
scanTask1.setScanAll( true );
scanTask1.setResourceFile( null );
scanList.add( scanTask1 );
RepositoryTask scanTask2 = new RepositoryTask( );
scanTask2.setRepositoryId( "testrepo2" );
scanTask2.setScanAll( true );
scanTask2.setResourceFile( null );
scanList.add( scanTask1 );

List<ArtifactIndexingTask> indexList = new ArrayList<>( );
ArtifactIndexingTask indexTask1 = mock( ArtifactIndexingTask.class, RETURNS_DEEP_STUBS );
when( indexTask1.getRepository( ).getId( ) ).thenReturn( "indexrepo1" );
when( indexTask1.isExecuteOnEntireRepo( ) ).thenReturn( true );
when( indexTask1.getResourceFile( ) ).thenReturn( null );
indexList.add( indexTask1 );
ArtifactIndexingTask indexTask2 = mock( ArtifactIndexingTask.class, RETURNS_DEEP_STUBS );
when( indexTask2.getRepository( ).getId( ) ).thenReturn( "indexrepo2" );
when( indexTask2.isExecuteOnEntireRepo( ) ).thenReturn( true );
when( indexTask2.getResourceFile( ) ).thenReturn( null );
indexList.add( indexTask2 );

when( scanningTaskExecutor.getQueue( ) ).thenReturn( queue );
when( indexingTaskExecutor.getQueue( ) ).thenReturn( indexQueue );
when( queue.getQueueSnapshot( ) ).thenReturn( scanList );
when( indexQueue.getQueueSnapshot( ) ).thenReturn( indexList );
ScanStatus currentScanStatus = taskAdministration.getCurrentScanStatus( );
assertNotNull( currentScanStatus );
assertNotNull( currentScanStatus.getIndexingQueue( ) );
assertNotNull( currentScanStatus.getScanQueue( ) );
assertEquals( 2, currentScanStatus.getScanQueue( ).size( ) );
assertEquals( 2, currentScanStatus.getIndexingQueue( ).size( ) );
}

@Test
public void testScanStatusWithId() throws RepositoryAdminException, TaskQueueException
{
TaskQueue queue = mock( TaskQueue.class );
TaskQueue indexQueue = mock( TaskQueue.class );

List<RepositoryTask> scanList = new ArrayList<>( );
RepositoryTask scanTask1 = new RepositoryTask( );
scanTask1.setRepositoryId( "abcde" );
scanTask1.setScanAll( true );
scanTask1.setResourceFile( null );
scanList.add( scanTask1 );
RepositoryTask scanTask2 = new RepositoryTask( );
scanTask2.setRepositoryId( "testrepo2" );
scanTask2.setScanAll( true );
scanTask2.setResourceFile( null );
scanList.add( scanTask1 );

List<ArtifactIndexingTask> indexList = new ArrayList<>( );
ArtifactIndexingTask indexTask1 = mock( ArtifactIndexingTask.class, RETURNS_DEEP_STUBS );
when( indexTask1.getRepository( ).getId( ) ).thenReturn( "indexrepo1" );
when( indexTask1.isExecuteOnEntireRepo( ) ).thenReturn( true );
when( indexTask1.getResourceFile( ) ).thenReturn( null );
indexList.add( indexTask1 );
ArtifactIndexingTask indexTask2 = mock( ArtifactIndexingTask.class, RETURNS_DEEP_STUBS );
when( indexTask2.getRepository( ).getId( ) ).thenReturn( "indexrepo2" );
when( indexTask2.isExecuteOnEntireRepo( ) ).thenReturn( true );
when( indexTask2.getResourceFile( ) ).thenReturn( null );
indexList.add( indexTask2 );

when( scanningTaskExecutor.getQueue( ) ).thenReturn( queue );
when( indexingTaskExecutor.getQueue( ) ).thenReturn( indexQueue );
when( queue.getQueueSnapshot( ) ).thenReturn( scanList );
when( indexQueue.getQueueSnapshot( ) ).thenReturn( indexList );
when( registry.getManagedRepository( "indexrepo2" ) ).thenReturn( mock( ManagedRepository.class ) );
ScanStatus currentScanStatus = taskAdministration.getCurrentScanStatus( "indexrepo2");
assertNotNull( currentScanStatus );
assertNotNull( currentScanStatus.getIndexingQueue( ) );
assertNotNull( currentScanStatus.getScanQueue( ) );
assertEquals( 0, currentScanStatus.getScanQueue( ).size( ) );
assertEquals( 1, currentScanStatus.getIndexingQueue( ).size( ) );
}

@Test
public void testScheduleFullScan() throws RepositoryAdminException, TaskQueueException
{
when( registry.getManagedRepository( "internal" ) ).thenReturn( mock( ManagedRepository.class ) );
taskAdministration.scheduleFullScan( "internal" );
verify( repositoryArchivaTaskScheduler, times(1) ).queueTask( any() );
verify( indexingArchivaTaskScheduler, times(1) ).queueTask( any() );
}

@Test
public void testScheduleIndexScan() throws RepositoryAdminException, TaskQueueException
{
when( registry.getManagedRepository( "internal" ) ).thenReturn( mock( ManagedRepository.class ) );
taskAdministration.scheduleIndexFullScan( "internal" );
ArgumentCaptor<ArtifactIndexingTask> captor = ArgumentCaptor.forClass( ArtifactIndexingTask.class );
verify( repositoryArchivaTaskScheduler, times(0) ).queueTask( any() );
verify( indexingArchivaTaskScheduler, times(1) ).queueTask( captor.capture() );
assertTrue(captor.getValue().isExecuteOnEntireRepo());
}

@Test
public void testScheduleIndexScanWithFile() throws RepositoryAdminException, TaskQueueException
{
ManagedRepository managedRepo = mock( ManagedRepository.class, RETURNS_DEEP_STUBS );
when( registry.getManagedRepository( "internal" ) ).thenReturn( managedRepo );
StorageAsset asset = mock( StorageAsset.class );
when( asset.getFilePath( ) ).thenReturn( Paths.get( "abc/def/ghij.pom" ) );
when( asset.exists( ) ).thenReturn( true );
when( registry.getManagedRepository( "internal" ).getAsset( "abc/def/ghij.pom" ) ).thenReturn( asset );
taskAdministration.scheduleIndexScan( "internal", "abc/def/ghij.pom" );
ArgumentCaptor<ArtifactIndexingTask> captor = ArgumentCaptor.forClass( ArtifactIndexingTask.class );
verify( repositoryArchivaTaskScheduler, times(0) ).queueTask( any() );
verify( indexingArchivaTaskScheduler, times(1) ).queueTask( captor.capture() );
ArtifactIndexingTask caption = captor.getValue( );
assertFalse(caption.isExecuteOnEntireRepo());
assertEquals( "abc/def/ghij.pom", caption.getResourceFile( ).toString() );
}

@Test
public void testScheduleMetadataScan() throws RepositoryAdminException, TaskQueueException
{
when( registry.getManagedRepository( "internal" ) ).thenReturn( mock( ManagedRepository.class ) );
taskAdministration.scheduleMetadataFullScan( "internal" );
ArgumentCaptor<RepositoryTask> captor = ArgumentCaptor.forClass( RepositoryTask.class );
verify( repositoryArchivaTaskScheduler, times(1) ).queueTask( captor.capture( ) );
verify( indexingArchivaTaskScheduler, times(0) ).queueTask( any() );
assertTrue(captor.getValue().isScanAll());
}

@Test
public void testScheduleMetadataUpdateScan() throws RepositoryAdminException, TaskQueueException
{
when( registry.getManagedRepository( "internal" ) ).thenReturn( mock( ManagedRepository.class ) );
taskAdministration.scheduleMetadataUpdateScan( "internal" );
ArgumentCaptor<RepositoryTask> captor = ArgumentCaptor.forClass( RepositoryTask.class );
verify( repositoryArchivaTaskScheduler, times(1) ).queueTask( captor.capture( ) );
verify( indexingArchivaTaskScheduler, times(0) ).queueTask( any() );
assertFalse(captor.getValue().isScanAll());
}


@Test
void cancelAllTasks() throws TaskQueueException, RepositoryAdminException
{
TaskQueue queue = mock( TaskQueue.class );
TaskQueue indexQueue = mock( TaskQueue.class );

List<RepositoryTask> scanList = new ArrayList<>( );
RepositoryTask scanTask1 = new RepositoryTask( );
scanTask1.setRepositoryId( "abcde" );
scanTask1.setScanAll( true );
scanTask1.setResourceFile( null );
scanList.add( scanTask1 );
RepositoryTask scanTask2 = new RepositoryTask( );
scanTask2.setRepositoryId( "testrepo2" );
scanTask2.setScanAll( true );
scanTask2.setResourceFile( null );
scanList.add( scanTask1 );

List<ArtifactIndexingTask> indexList = new ArrayList<>( );
ArtifactIndexingTask indexTask1 = mock( ArtifactIndexingTask.class, RETURNS_DEEP_STUBS );
when( indexTask1.getRepository( ).getId( ) ).thenReturn( "indexrepo1" );
when( indexTask1.isExecuteOnEntireRepo( ) ).thenReturn( true );
when( indexTask1.getResourceFile( ) ).thenReturn( null );
indexList.add( indexTask1 );
ArtifactIndexingTask indexTask2 = mock( ArtifactIndexingTask.class, RETURNS_DEEP_STUBS );
when( indexTask2.getRepository( ).getId( ) ).thenReturn( "indexrepo2" );
when( indexTask2.isExecuteOnEntireRepo( ) ).thenReturn( true );
when( indexTask2.getResourceFile( ) ).thenReturn( null );
indexList.add( indexTask2 );

when( scanningTaskExecutor.getQueue( ) ).thenReturn( queue );
when( indexingTaskExecutor.getQueue( ) ).thenReturn( indexQueue );
when( queue.getQueueSnapshot( ) ).thenReturn( scanList );
when( indexQueue.getQueueSnapshot( ) ).thenReturn( indexList );
taskAdministration.cancelTasks( "indexrepo1" );
ArgumentCaptor<List> scanCaptor = ArgumentCaptor.forClass( List.class );
ArgumentCaptor<List> indexCaptor = ArgumentCaptor.forClass( List.class );

verify( queue ).removeAll( scanCaptor.capture() );
verify( indexQueue ).removeAll( indexCaptor.capture() );

List scanCancelList = scanCaptor.getValue( );
List indexCancelList = indexCaptor.getValue( );
assertEquals( 0, scanCancelList.size( ) );
assertEquals( 1, indexCancelList.size( ) );
assertEquals( "indexrepo1", ( (ArtifactIndexingTask) indexCancelList.get( 0 ) ).getRepository( ).getId( ) );


}
}

+ 2
- 1
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/resources/spring-context.xml Visa fil

@@ -31,8 +31,9 @@
default-lazy-init="true">

<context:annotation-config/>
<context:component-scan base-package="org.apache.archiva.admin.mock,org.apache.archiva.repository.content.maven2"/>
<context:component-scan base-package="org.apache.archiva.admin.mock,org.apache.archiva.repository.content.base"/>

<alias name="archivaTaskScheduler#mock" alias="archivaTaskScheduler#default" />
<bean name="scheduler" class="org.apache.archiva.components.scheduler.DefaultScheduler">
<property name="properties">
<props>

+ 6
- 6
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/IndexingTask.java Visa fil

@@ -37,13 +37,13 @@ public class IndexingTask implements Serializable
private boolean running = false;
private long maxExecutionTimeMs = 0;

public static IndexingTask of( ArtifactIndexingTask repositoryTask ) {
public static IndexingTask of( org.apache.archiva.admin.model.beans.IndexingTask repositoryTask ) {
IndexingTask indexingTask = new IndexingTask( );
indexingTask.setFullRepository( repositoryTask.isExecuteOnEntireRepo());
indexingTask.setUpdateOnly( repositoryTask.isOnlyUpdate() );
indexingTask.setResource( repositoryTask.getResourceFile( ).toString( ) );
indexingTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTime() );
indexingTask.setRepositoryId( repositoryTask.getRepository().getId() );
indexingTask.setFullRepository( repositoryTask.isFullScan());
indexingTask.setUpdateOnly( repositoryTask.isUpdateOnly() );
indexingTask.setResource( repositoryTask.getResource() );
indexingTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTimeMs() );
indexingTask.setRepositoryId( repositoryTask.getRepositoryId() );
return indexingTask;
}


+ 10
- 2
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/Repository.java Visa fil

@@ -97,10 +97,18 @@ public class Repository implements Serializable
} else {
myLocale = locale;
}
String repoName = repository.getName( myLocale );
if (repoName==null) {
repoName = repository.getName( );
}
String description = repository.getDescription( myLocale );
if (description==null) {
description = repository.getDescription( );
}
Repository newRepo = new Repository( );
newRepo.setId( repository.getId() );
newRepo.setName( repository.getName( myLocale ) );
newRepo.setDescription( repository.getDescription( myLocale ) );
newRepo.setName( repoName );
newRepo.setDescription( description );
newRepo.setLocation( repository.getLocation().toASCIIString() );
newRepo.setIndex( repository.hasIndex() );
newRepo.setLayout( repository.getLayout() );

+ 12
- 23
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanStatus.java Visa fil

@@ -18,6 +18,7 @@ package org.apache.archiva.rest.api.model.v2;
*/

import io.swagger.v3.oas.annotations.media.Schema;
import org.apache.archiva.admin.model.beans.MetadataScanTask;
import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
import org.apache.archiva.scheduler.repository.model.RepositoryTask;

@@ -43,30 +44,18 @@ public class ScanStatus implements Serializable
{
}

public void updateScanInfo( RepositoryTask runningRepositoryTask, List<RepositoryTask> taskQueue) {
List<ScanTask> newScanQueue = new ArrayList<>( );
if (runningRepositoryTask==null) {
this.scanRunning=false;
} else {
this.scanRunning=true;
newScanQueue.add( 0, ScanTask.of( runningRepositoryTask ) );
}
newScanQueue.addAll( taskQueue.stream( ).map( task -> ScanTask.of( task ) ).collect( Collectors.toList( ) ) );
this.scanQueued = taskQueue.size( );
this.scanQueue = newScanQueue;
}
public static ScanStatus of( org.apache.archiva.admin.model.beans.ScanStatus modelStatus ) {
ScanStatus status = new ScanStatus( );
status.setIndexRunning( modelStatus.isIndexScanRunning() );
status.setScanRunning( modelStatus.isMetadataScanRunning() );
List<org.apache.archiva.admin.model.beans.IndexingTask> indexQueue = modelStatus.getIndexingQueue( );
status.setIndexingQueue( indexQueue.stream().map(IndexingTask::of).collect( Collectors.toList()) );
status.setIndexQueued( indexQueue.size( ) > 0 ? indexQueue.size( ) - 1 : 0 );
List<MetadataScanTask> scanQueue = modelStatus.getScanQueue( );
status.setScanQueue( scanQueue.stream().map( ScanTask::of ).collect( Collectors.toList()) );
status.setScanQueued( scanQueue.size( ) > 0 ? scanQueue.size( ) - 1 : 0 );
return status;

public void updateIndexInfo( ArtifactIndexingTask runningIndexingTask, List<ArtifactIndexingTask> taskQueue) {
List<IndexingTask> newIndexQueue = new ArrayList<>( );
if (runningIndexingTask==null) {
this.indexRunning=false;
} else {
this.indexRunning=true;
newIndexQueue.add(IndexingTask.of( runningIndexingTask ) );
}
newIndexQueue.addAll( taskQueue.stream( ).map( task -> IndexingTask.of( task ) ).collect( Collectors.toList( ) ) );
this.indexQueued = taskQueue.size( );
this.indexingQueue = newIndexQueue;
}

@Schema( name = "scan_running", description = "True, if a scan is currently running" )

+ 5
- 4
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanTask.java Visa fil

@@ -18,6 +18,7 @@ package org.apache.archiva.rest.api.model.v2;
*/

import io.swagger.v3.oas.annotations.media.Schema;
import org.apache.archiva.admin.model.beans.MetadataScanTask;
import org.apache.archiva.scheduler.repository.model.RepositoryTask;

import java.io.Serializable;
@@ -36,12 +37,12 @@ public class ScanTask implements Serializable
private String resource = "";
private long maxExecutionTimeMs = 0;

public static ScanTask of( RepositoryTask repositoryTask ) {
public static ScanTask of( MetadataScanTask repositoryTask ) {
ScanTask scanTask = new ScanTask( );
scanTask.setFullRepository( repositoryTask.isScanAll());
scanTask.setFullRepository( repositoryTask.isFullScan());
scanTask.setUpdateRelatedArtifacts( repositoryTask.isUpdateRelatedArtifacts() );
scanTask.setResource( repositoryTask.getResourceFile( ).toString( ) );
scanTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTime() );
scanTask.setResource( repositoryTask.getResource() );
scanTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTimeMs() );
scanTask.setRepositoryId( repositoryTask.getRepositoryId( ) );
return scanTask;
}

archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/ErrorKeys.java → archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/ErrorKeys.java Visa fil

@@ -1,4 +1,4 @@
package org.apache.archiva.rest.services.v2;/*
package org.apache.archiva.rest.api.services.v2;/*
* 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

+ 0
- 4
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryService.java Visa fil

@@ -144,10 +144,6 @@ public interface RepositoryService
throws ArchivaRestServiceException;


/**
* scan directories
* @since 1.4-M3
*/
@Path ("managed/{id}/scan/now")
@POST
@Produces ({ APPLICATION_JSON })

+ 1
- 0
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultMavenManagedRepositoryService.java Visa fil

@@ -24,6 +24,7 @@ import org.apache.archiva.components.rest.util.QueryHelper;
import org.apache.archiva.rest.api.model.v2.FileInfo;
import org.apache.archiva.rest.api.model.v2.MavenManagedRepository;
import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.v2.ErrorKeys;
import org.apache.archiva.rest.api.services.v2.ErrorMessage;
import org.apache.archiva.rest.api.services.v2.MavenManagedRepositoryService;
import org.slf4j.Logger;

+ 1
- 0
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryGroupService.java Visa fil

@@ -46,6 +46,7 @@ import org.apache.archiva.redback.rest.services.RedbackRequestInformation;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.rest.api.model.v2.RepositoryGroup;
import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.v2.ErrorKeys;
import org.apache.archiva.rest.api.services.v2.ErrorMessage;
import org.apache.archiva.rest.api.services.v2.RepositoryGroupService;
import org.apache.commons.lang3.StringUtils;

+ 53
- 59
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryService.java Visa fil

@@ -17,11 +17,10 @@ package org.apache.archiva.rest.services.v2;
* under the License.
*/

import org.apache.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.admin.RepositoryTaskAdministration;
import org.apache.archiva.components.rest.model.PagedResult;
import org.apache.archiva.components.rest.util.QueryHelper;
import org.apache.archiva.components.taskqueue.Task;
import org.apache.archiva.components.taskqueue.TaskQueueException;
import org.apache.archiva.components.taskqueue.execution.TaskQueueExecutor;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
import org.apache.archiva.repository.RepositoryRegistry;
@@ -33,19 +32,14 @@ import org.apache.archiva.rest.api.model.v2.Repository;
import org.apache.archiva.rest.api.model.v2.RepositoryStatistics;
import org.apache.archiva.rest.api.model.v2.ScanStatus;
import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.v2.ErrorKeys;
import org.apache.archiva.rest.api.services.v2.ErrorMessage;
import org.apache.archiva.rest.api.services.v2.RepositoryService;
import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
import org.apache.archiva.scheduler.indexing.IndexingArchivaTaskScheduler;
import org.apache.archiva.scheduler.indexing.maven.ArchivaIndexingTaskExecutor;
import org.apache.archiva.scheduler.repository.model.RepositoryArchivaTaskScheduler;
import org.apache.archiva.scheduler.repository.model.RepositoryTask;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.core.Response;
import java.util.Comparator;
@@ -58,49 +52,64 @@ import java.util.stream.Collectors;
* @author Martin Stockhammer <martin_s@apache.org>
* @since 3.0
*/
@Service("v2.repositoryService#rest")
@Service( "v2.repositoryService#rest" )
public class DefaultRepositoryService implements RepositoryService
{

@Inject
final
RepositoryRegistry repositoryRegistry;

@Inject
final
RepositoryStatisticsManager repositoryStatisticsManager;

@Inject
@Named(value="taskQueueExecutor#indexing")
TaskQueueExecutor<ArtifactIndexingTask> indexingTaskExecutor;
private final RepositoryTaskAdministration repositoryTaskAdministration;

@Inject
@Named(value="taskQueueExecutor#repository-scanning")
TaskQueueExecutor<RepositoryTask> scanningTaskExecutor;

@Inject
@Named(value = "archivaTaskScheduler#repository")
private RepositoryArchivaTaskScheduler repositoryArchivaTaskScheduler;

@Inject
@Named( value = "archivaTaskScheduler#indexing" )
private IndexingArchivaTaskScheduler indexingArchivaTaskScheduler;

@Inject
private RepositoryScanner repoScanner;
private final RepositoryScanner repoScanner;


private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryService.class );
private static final QueryHelper<org.apache.archiva.repository.Repository> QUERY_HELPER = new QueryHelper<>( new String[]{"id", "name"} );

static
{
QUERY_HELPER.addStringFilter( "id", org.apache.archiva.repository.Repository::getId );
QUERY_HELPER.addStringFilter( "name", org.apache.archiva.repository.Repository::getName );
QUERY_HELPER.addStringFilter( "description", org.apache.archiva.repository.Repository::getDescription );
QUERY_HELPER.addStringFilter( "type", repo -> repo.getType( ).name( ) );
QUERY_HELPER.addBooleanFilter( "scanned", org.apache.archiva.repository.Repository::isScanned );
QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.repository.Repository::getId );
QUERY_HELPER.addNullsafeFieldComparator( "name", org.apache.archiva.repository.Repository::getName );
QUERY_HELPER.addNullsafeFieldComparator( "type", repo -> repo.getType( ).name( ) );
QUERY_HELPER.addNullsafeFieldComparator( "boolean", org.apache.archiva.repository.Repository::isScanned );
}

public DefaultRepositoryService( RepositoryRegistry repositoryRegistry, RepositoryStatisticsManager repositoryStatisticsManager,
@Named( value = "repositoryTaskAdministration#default") RepositoryTaskAdministration repositoryTaskAdministration,
RepositoryScanner repoScanner )
{
this.repositoryRegistry = repositoryRegistry;
this.repositoryStatisticsManager = repositoryStatisticsManager;
this.repoScanner = repoScanner;
this.repositoryTaskAdministration = repositoryTaskAdministration;
}

private void handleAdminException( RepositoryAdminException e ) throws ArchivaRestServiceException
{
log.error( "Repository admin error: {}", e.getMessage( ), e );
if ( e.keyExists( ) )
{
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PREFIX + e.getKey( ), e.getParameters( ) ) );
}
else
{
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
}
}


@Override
public PagedResult<Repository> getRepositories( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order,
String localeString) throws ArchivaRestServiceException
String localeString ) throws ArchivaRestServiceException
{
final Locale locale = StringUtils.isNotEmpty( localeString ) ? Locale.forLanguageTag( localeString ) : Locale.getDefault( );
boolean isAscending = QUERY_HELPER.isAscending( order );
@@ -123,7 +132,8 @@ public class DefaultRepositoryService implements RepositoryService
@Override
public RepositoryStatistics getManagedRepositoryStatistics( String repositoryId ) throws ArchivaRestServiceException
{
if (repositoryRegistry.getManagedRepository( repositoryId )==null) {
if ( repositoryRegistry.getManagedRepository( repositoryId ) == null )
{
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_MANAGED_NOT_FOUND, repositoryId ), 404 );
}
try
@@ -142,17 +152,13 @@ public class DefaultRepositoryService implements RepositoryService
{
try
{
org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
ArtifactIndexingTask task =
new ArtifactIndexingTask( repository, null, ArtifactIndexingTask.Action.FINISH, repository.getIndexingContext() );
task.setExecuteOnEntireRepo( true );
task.setOnlyUpdate( !fullScan );
indexingArchivaTaskScheduler.queueTask( task );
repositoryArchivaTaskScheduler.queueTask( new RepositoryTask( repositoryId, fullScan ) );
repositoryTaskAdministration.scheduleFullScan( repositoryId );
return Response.ok( ).build( );
} catch ( TaskQueueException e ) {
log.error( "Could not queue the task: {}", e.getMessage( ), e );
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.TASK_QUEUE_FAILED, e.getMessage( ) ) );
}
catch ( RepositoryAdminException e )
{
handleAdminException( e );
return Response.serverError( ).build( );
}
}

@@ -166,34 +172,22 @@ public class DefaultRepositoryService implements RepositoryService
}
catch ( RepositoryScannerException e )
{
log.error( e.getMessage(), e );
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_SCAN_FAILED, e.getMessage() ));
log.error( e.getMessage( ), e );
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_SCAN_FAILED, e.getMessage( ) ) );
}
}

@Override
public ScanStatus getScanStatus( String repositoryId ) throws ArchivaRestServiceException
{
ScanStatus status = new ScanStatus( );
try
{
RepositoryTask scanTask = scanningTaskExecutor.getCurrentTask( );
if ( !repositoryId.equals( scanTask.getRepositoryId( ) ) )
{
scanTask=null;
}
ArtifactIndexingTask indexTask = indexingTaskExecutor.getCurrentTask( );
if (!repositoryId.equals(indexTask.getRepository().getId())) {
indexTask = null;
}
status.updateScanInfo( scanTask, scanningTaskExecutor.getQueue( ).getQueueSnapshot( ).stream( ).filter( task -> repositoryId.equals(task.getRepositoryId()) ).collect( Collectors.toList() ) );
status.updateIndexInfo( indexTask, indexingTaskExecutor.getQueue( ).getQueueSnapshot( ).stream().filter( task -> repositoryId.equals(task.getRepository().getId())).collect( Collectors.toList()) );
return status;
return ScanStatus.of( repositoryTaskAdministration.getCurrentScanStatus( ) );
}
catch ( TaskQueueException e )
catch ( RepositoryAdminException e )
{
log.error( "Could not get task information: {}", e.getMessage( ), e );
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.TASK_QUEUE_FAILED, e.getMessage( ) ) );
handleAdminException( e );
return null;
}
}


+ 3
- 2
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultSecurityConfigurationService.java Visa fil

@@ -56,6 +56,7 @@ import org.apache.archiva.rest.api.model.v2.CacheConfiguration;
import org.apache.archiva.rest.api.model.v2.LdapConfiguration;
import org.apache.archiva.rest.api.model.v2.SecurityConfiguration;
import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.v2.ErrorKeys;
import org.apache.archiva.rest.api.services.v2.ErrorMessage;
import org.apache.archiva.rest.api.services.v2.SecurityConfigurationService;
import org.apache.commons.collections4.CollectionUtils;
@@ -87,8 +88,8 @@ import java.util.ResourceBundle;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static org.apache.archiva.rest.services.v2.ErrorKeys.INVALID_RESULT_SET_ERROR;
import static org.apache.archiva.rest.services.v2.ErrorKeys.REPOSITORY_ADMIN_ERROR;
import static org.apache.archiva.rest.api.services.v2.ErrorKeys.INVALID_RESULT_SET_ERROR;
import static org.apache.archiva.rest.api.services.v2.ErrorKeys.REPOSITORY_ADMIN_ERROR;

/**
* @author Martin Stockhammer <martin_s@apache.org>

+ 162
- 0
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/v2/NativeRepositoryServiceTest.java Visa fil

@@ -0,0 +1,162 @@
package org.apache.archiva.rest.services.v2;

/*
* 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 io.restassured.response.Response;
import org.apache.archiva.components.rest.model.PagedResult;
import org.apache.archiva.rest.api.model.v2.Repository;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestMethodOrder;

import java.util.List;

import static io.restassured.RestAssured.given;
import static io.restassured.http.ContentType.JSON;
import static org.junit.jupiter.api.Assertions.*;

/**
* @author Martin Stockhammer <martin_s@apache.org>
*/
@TestInstance( TestInstance.Lifecycle.PER_CLASS )
@Tag( "rest-native" )
@TestMethodOrder( MethodOrderer.Random.class )
@DisplayName( "Native REST tests for V2 RepositoryService" )
public class NativeRepositoryServiceTest extends AbstractNativeRestServices
{
@Override
protected String getServicePath( )
{
return "/repositories";
}

@BeforeAll
void setup( ) throws Exception
{
super.setupNative( );
}

@AfterAll
void destroy( ) throws Exception
{
super.shutdownNative( );
}

@Test
void testGetRepositories() {
String token = getAdminToken( );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.get( "" )
.prettyPeek()
.then( ).statusCode( 200 ).extract( ).response( );
assertNotNull( response );
PagedResult<Repository> repositoryPagedResult = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
assertEquals( 3, repositoryPagedResult.getPagination( ).getTotalCount( ) );
List<Repository> data = response.getBody( ).jsonPath( ).getList( "data", Repository.class );
assertTrue( data.stream( ).anyMatch( p -> "central".equals( p.getId( ) ) ) );
assertTrue( data.stream( ).anyMatch( p -> "internal".equals( p.getId( ) ) ) );
assertTrue( data.stream( ).anyMatch( p -> "snapshots".equals( p.getId( ) ) ) );
Repository snapshotRepo = data.stream( ).filter( p -> "snapshots".equals( p.getId( ) ) ).findFirst( ).get( );
assertEquals( "Archiva Managed Snapshot Repository", snapshotRepo.getName( ) );
assertEquals( "MAVEN", snapshotRepo.getType() );
assertEquals( "managed", snapshotRepo.getCharacteristic() );
assertEquals( "default", snapshotRepo.getLayout() );
assertTrue( snapshotRepo.isScanned( ) );
assertTrue( snapshotRepo.isIndex( ) );

Repository centralRepo = data.stream( ).filter( p -> "central".equals( p.getId( ) ) ).findFirst( ).get( );
assertEquals( "Central Repository", centralRepo.getName( ) );
assertEquals( "MAVEN", centralRepo.getType() );
assertEquals( "remote", centralRepo.getCharacteristic() );
assertEquals( "default", centralRepo.getLayout() );


}

@Test
void testGetFilteredRepositories() {
String token = getAdminToken( );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.queryParam( "q", "central" )
.get( "" )
.prettyPeek()
.then( ).statusCode( 200 ).extract( ).response( );
assertNotNull( response );
PagedResult<Repository> repositoryPagedResult = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
assertEquals( 1, repositoryPagedResult.getPagination( ).getTotalCount( ) );
List<Repository> data = response.getBody( ).jsonPath( ).getList( "data", Repository.class );
assertTrue( data.stream( ).anyMatch( p -> "central".equals( p.getId( ) ) ) );
}


@Test
void getStatistics() {
String token = getAdminToken( );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.get( "managed/internal/statistics" )
.prettyPeek()
.then( ).statusCode( 200 ).extract( ).response( );
assertNotNull( response );

}

@Test
void scheduleScan() {
String token = getAdminToken( );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.post( "managed/internal/scan/schedule" )
.prettyPeek()
.then( ).statusCode( 200 ).extract( ).response( );
assertNotNull( response );

}

@Test
void immediateScan() {
String token = getAdminToken( );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.post( "managed/internal/scan/now" )
.prettyPeek()
.then( ).statusCode( 200 ).extract( ).response( );
assertNotNull( response );

}

@Test
void scanStatus() {
String token = getAdminToken( );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.get( "managed/internal/scan/status" )
.prettyPeek()
.then( ).statusCode( 200 ).extract( ).response( );
assertNotNull( response );

}
}

Laddar…
Avbryt
Spara