]> source.dussan.org Git - archiva.git/commitdiff
Adding REST v2 interfaces
authorMartin Stockhammer <martin_s@apache.org>
Sat, 23 Jan 2021 18:33:10 +0000 (19:33 +0100)
committerMartin Stockhammer <martin_s@apache.org>
Sat, 23 Jan 2021 18:33:10 +0000 (19:33 +0100)
39 files changed:
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/RepositoryGroup.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/pom.xml
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/SearchRequest.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/Artifact.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ArtifactTransferRequest.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/BeanInformation.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/FileInfo.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/IndexingTask.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/LdapConfiguration.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MavenManagedRepository.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MavenRemoteRepository.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MergeConfiguration.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/Repository.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryGroup.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryStatistics.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanStatus.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanTask.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/SecurityConfiguration.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/ArtifactCleanupInfo.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/IndexCreationInfo.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/RemoteIndexInfo.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/StagingInfo.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/ManagedRepositoriesService.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/ArchivaRestServiceException.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/Configuration.java [deleted file]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/MavenManagedRepositoryService.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryGroupService.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryService.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RestConfiguration.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/SecurityConfigurationService.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultManagedRepositoriesService.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultMavenManagedRepositoryService.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryGroupService.java
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryService.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultSecurityConfigurationService.java
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-services/src/main/resources/META-INF/spring-context.xml
archiva-modules/metadata/metadata-statistics-api/src/main/java/org/apache/archiva/metadata/repository/stats/model/DefaultRepositoryStatistics.java
archiva-modules/metadata/metadata-statistics-api/src/main/java/org/apache/archiva/metadata/repository/stats/model/RepositoryStatistics.java

index 7e39a3d80db39d55460a665b07b09e991e5fb4a2..d4c0041b290f5856c5e7395bbd7338f713ab8d47 100644 (file)
@@ -51,7 +51,7 @@ public class RepositoryGroup
     /**
      * The TTL (time to live) of the repo group's merged index.
      */
-    private int mergedIndexTtl = -1;
+    private int mergedIndexTtl = 30;
 
     /**
      * default model value is empty so none
index 67efa7acda8fe2eb32c1eeddb24cdd9b100ffa3d..ac1b0623cfbff7a9be18d819a30228b34828ac76 100644 (file)
       <groupId>org.apache.archiva</groupId>
       <artifactId>archiva-repository-scanner</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.archiva</groupId>
+      <artifactId>archiva-scheduler-repository-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.archiva</groupId>
+      <artifactId>archiva-scheduler-indexing</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>org.apache.archiva</groupId>
index e38706ca0cf43ec2aa24dae9d4703b809edb41ed..cc470d9dc2adb3a7ab757b705dbac16673861f12 100644 (file)
@@ -1,5 +1,23 @@
 package org.apache.archiva.rest.api.model;
 
+/*
+ * 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 javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
 import java.util.ArrayList;
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/Artifact.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/Artifact.java
new file mode 100644 (file)
index 0000000..c8fae1e
--- /dev/null
@@ -0,0 +1,43 @@
+package org.apache.archiva.rest.api.model.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.swagger.v3.oas.annotations.media.Schema;
+
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="Artifact", description = "Information about artifacts")
+public class Artifact implements Serializable
+{
+    private static final long serialVersionUID = 7581578317346876555L;
+    private String name;
+
+    @Schema(name="name",description = "The name of the artifact")
+    public String getName( )
+    {
+        return name;
+    }
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ArtifactTransferRequest.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ArtifactTransferRequest.java
new file mode 100644 (file)
index 0000000..ce22bc4
--- /dev/null
@@ -0,0 +1,43 @@
+package org.apache.archiva.rest.api.model.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.swagger.v3.oas.annotations.media.Schema;
+
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class ArtifactTransferRequest implements Serializable
+{
+    private static final long serialVersionUID = -7377281345536573342L;
+
+    private String path;
+
+    @Schema(description = "The path to the artifact")
+    public String getPath( )
+    {
+        return path;
+    }
+
+    public void setPath( String path )
+    {
+        this.path = path;
+    }
+}
index 936ace0a31e0b5a3b3554aef34f26be9ed0873c8..b795acddc8b3eaf8bf4baf48e62ebce0092f4c50 100644 (file)
@@ -16,6 +16,24 @@ package org.apache.archiva.rest.api.model.v2;/*
  * under the License.
  */
 
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
 
 import javax.xml.bind.annotation.XmlRootElement;
@@ -30,11 +48,11 @@ import java.util.Objects;
 public class BeanInformation implements Serializable
 {
     private static final long serialVersionUID = -432385743277355987L;
-    String id;
-    String displayName;
-    String descriptionKey;
-    String defaultDescription;
-    boolean readonly;
+    private String id;
+    private String displayName;
+    private String descriptionKey;
+    private String defaultDescription;
+    private boolean readonly;
 
     public BeanInformation( )
     {
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/FileInfo.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/FileInfo.java
new file mode 100644 (file)
index 0000000..e1f423d
--- /dev/null
@@ -0,0 +1,118 @@
+package org.apache.archiva.rest.api.model.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.
+ */
+
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
+
+import java.io.Serializable;
+import java.time.OffsetDateTime;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="FileInfo",description = "Information about a file stored in the repository")
+public class FileInfo implements Serializable
+{
+    private static final long serialVersionUID = 900497784542880195L;
+    private OffsetDateTime modified;
+    private String fileName;
+    private String path;
+
+    @Schema(description = "Time when the file was last modified")
+    public OffsetDateTime getModified( )
+    {
+        return modified;
+    }
+
+    public void setModified( OffsetDateTime modified )
+    {
+        this.modified = modified;
+    }
+
+    @Schema(name="file_name", description = "Name of the file")
+    public String getFileName( )
+    {
+        return fileName;
+    }
+
+    public void setFileName( String fileName )
+    {
+        this.fileName = fileName;
+    }
+
+    @Schema(name="path", description = "Path to the file relative to the repository directory")
+    public String getPath( )
+    {
+        return path;
+    }
+
+    public void setPath( String path )
+    {
+        this.path = path;
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o ) return true;
+        if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+        FileInfo fileInfo = (FileInfo) o;
+
+        if ( modified != null ? !modified.equals( fileInfo.modified ) : fileInfo.modified != null ) return false;
+        if ( fileName != null ? !fileName.equals( fileInfo.fileName ) : fileInfo.fileName != null ) return false;
+        return path != null ? path.equals( fileInfo.path ) : fileInfo.path == null;
+    }
+
+    @Override
+    public int hashCode( )
+    {
+        int result = modified != null ? modified.hashCode( ) : 0;
+        result = 31 * result + ( fileName != null ? fileName.hashCode( ) : 0 );
+        result = 31 * result + ( path != null ? path.hashCode( ) : 0 );
+        return result;
+    }
+
+    @Override
+    public String toString( )
+    {
+        final StringBuilder sb = new StringBuilder( "FileInfo{" );
+        sb.append( "modified=" ).append( modified );
+        sb.append( ", fileName='" ).append( fileName ).append( '\'' );
+        sb.append( ", path='" ).append( path ).append( '\'' );
+        sb.append( '}' );
+        return sb.toString( );
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/IndexingTask.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/IndexingTask.java
new file mode 100644 (file)
index 0000000..e4d6684
--- /dev/null
@@ -0,0 +1,158 @@
+package org.apache.archiva.rest.api.model.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.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
+import org.apache.archiva.scheduler.repository.model.RepositoryTask;
+
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="IndexingTask",description = "Information about indexing tasks")
+public class IndexingTask implements Serializable
+{
+    private static final long serialVersionUID = -1947200162602613310L;
+    private String repositoryId = "";
+    private boolean fullRepository;
+    private boolean updateOnly;
+    private String resource = "";
+    private boolean running = false;
+    private long maxExecutionTimeMs = 0;
+
+    public static IndexingTask of( ArtifactIndexingTask 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() );
+        return indexingTask;
+    }
+
+    @Schema(name="repository_id",description = "Identifier of the repository this task is running on")
+    public String getRepositoryId( )
+    {
+        return repositoryId;
+    }
+
+    public void setRepositoryId( String repositoryId )
+    {
+        this.repositoryId = repositoryId==null?"":repositoryId;
+    }
+
+    @Schema( name = "full_repository", description = "True, if this is a full repository index scan" )
+    public boolean isFullRepository( )
+    {
+        return fullRepository;
+    }
+
+    public void setFullRepository( boolean fullRepository )
+    {
+        this.fullRepository = fullRepository;
+    }
+
+    @Schema(name="update_only", description = "True, if this is only updating the index with new files")
+    public boolean isUpdateOnly( )
+    {
+        return updateOnly;
+    }
+
+    public void setUpdateOnly( boolean updateOnly )
+    {
+        this.updateOnly = updateOnly;
+    }
+
+    @Schema(name="resource",description = "The resource that should be updated, if this is not a full repo update")
+    public String getResource( )
+    {
+        return resource;
+    }
+
+    public void setResource( String resource )
+    {
+        this.resource = resource == null ? "" : resource;
+    }
+
+    @Schema(name="running", description = "True, if this task is currently running")
+    public boolean isRunning( )
+    {
+        return running;
+    }
+
+    public void setRunning( boolean running )
+    {
+        this.running = running;
+    }
+
+    @Schema(name="max_execution_time_ms",description = "Maximum task execution time in ms")
+    public long getMaxExecutionTimeMs( )
+    {
+        return maxExecutionTimeMs;
+    }
+
+    public void setMaxExecutionTimeMs( long maxExecutionTimeMs )
+    {
+        this.maxExecutionTimeMs = maxExecutionTimeMs;
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o ) return true;
+        if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+        IndexingTask that = (IndexingTask) o;
+
+        if ( fullRepository != that.fullRepository ) return false;
+        if ( updateOnly != that.updateOnly ) return false;
+        if ( running != that.running ) return false;
+        if ( maxExecutionTimeMs != that.maxExecutionTimeMs ) return false;
+        if ( !repositoryId.equals( that.repositoryId ) ) return false;
+        return resource.equals( that.resource );
+    }
+
+    @Override
+    public int hashCode( )
+    {
+        int result = repositoryId.hashCode( );
+        result = 31 * result + ( fullRepository ? 1 : 0 );
+        result = 31 * result + ( updateOnly ? 1 : 0 );
+        result = 31 * result + resource.hashCode( );
+        result = 31 * result + ( running ? 1 : 0 );
+        result = 31 * result + (int) ( maxExecutionTimeMs ^ ( maxExecutionTimeMs >>> 32 ) );
+        return result;
+    }
+
+    @Override
+    public String toString( )
+    {
+        final StringBuilder sb = new StringBuilder( "IndexingTask{" );
+        sb.append( "repositoryId='" ).append( repositoryId ).append( '\'' );
+        sb.append( ", fullRepository=" ).append( fullRepository );
+        sb.append( ", updateOnly=" ).append( updateOnly );
+        sb.append( ", resource='" ).append( resource ).append( '\'' );
+        sb.append( ", running=" ).append( running );
+        sb.append( ", maxExecutionTimeMs=" ).append( maxExecutionTimeMs );
+        sb.append( '}' );
+        return sb.toString( );
+    }
+
+}
index d6802c6f2bf2983bdc848e5caaef804027e51696..d6d481a150ce3ce1bb48acfd5b75c3cf16f0150e 100644 (file)
@@ -16,10 +16,29 @@ package org.apache.archiva.rest.api.model.v2;/*
  * under the License.
  */
 
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
 
 import javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -46,7 +65,7 @@ public class LdapConfiguration implements Serializable
     private boolean sslEnabled = false;
     private boolean bindAuthenticatorEnabled = true;
     private boolean useRoleNameAsGroup = false;
-    private final Map<String, String> properties = new TreeMap<>();
+    private Map<String, String> properties = new TreeMap<>();
     private boolean writable = false;
     private List<String> availableContextFactories;
 
@@ -206,8 +225,11 @@ public class LdapConfiguration implements Serializable
 
     public void setProperties( Map<String, String> properties )
     {
-        this.properties.clear();
-        this.properties.putAll( properties );
+        this.properties = new TreeMap<>( properties  );
+    }
+
+    public void addProperty(String key, String value) {
+        this.properties.put( key, value );
     }
 
     @Schema(description = "True, if attributes in the the LDAP server can be edited by Archiva")
@@ -229,7 +251,13 @@ public class LdapConfiguration implements Serializable
 
     public void setAvailableContextFactories( List<String> availableContextFactories )
     {
-        this.availableContextFactories = availableContextFactories;
+        this.availableContextFactories = new ArrayList<>( availableContextFactories );
+    }
+
+    public void addAvailableContextFactory(String contextFactory) {
+        if (!this.availableContextFactories.contains( contextFactory ) ) {
+            this.availableContextFactories.add( contextFactory );
+        }
     }
 
 
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MavenManagedRepository.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MavenManagedRepository.java
new file mode 100644 (file)
index 0000000..6a045b4
--- /dev/null
@@ -0,0 +1,115 @@
+package org.apache.archiva.rest.api.model.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.
+ */
+
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="MavenManagedRepository",description = "A managed repository stores artifacts locally")
+public class MavenManagedRepository extends Repository
+{
+    private static final long serialVersionUID = -6853748886201905029L;
+
+    boolean blocksRedeployments;
+    List<String> releaseSchemes = new ArrayList<>(  );
+
+    @Schema(name="blocks_redeployments",description = "True, if redeployments to this repository are not allowed")
+    public boolean isBlocksRedeployments( )
+    {
+        return blocksRedeployments;
+    }
+
+    public void setBlocksRedeployments( boolean blocksRedeployments )
+    {
+        this.blocksRedeployments = blocksRedeployments;
+    }
+
+    @Schema(name="release_schemes", description = "The release schemes this repository is used for (e.g. RELEASE, SNAPSHOT)")
+    public List<String> getReleaseSchemes( )
+    {
+        return releaseSchemes;
+    }
+
+    public void setReleaseSchemes( List<String> releaseSchemes )
+    {
+        this.releaseSchemes = new ArrayList<>( releaseSchemes );
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o ) return true;
+        if ( o == null || getClass( ) != o.getClass( ) ) return false;
+        if ( !super.equals( o ) ) return false;
+
+        MavenManagedRepository that = (MavenManagedRepository) o;
+
+        if ( blocksRedeployments != that.blocksRedeployments ) return false;
+        return releaseSchemes != null ? releaseSchemes.equals( that.releaseSchemes ) : that.releaseSchemes == null;
+    }
+
+    @Override
+    public int hashCode( )
+    {
+        int result = super.hashCode( );
+        result = 31 * result + ( blocksRedeployments ? 1 : 0 );
+        result = 31 * result + ( releaseSchemes != null ? releaseSchemes.hashCode( ) : 0 );
+        return result;
+    }
+
+    @Override
+    public String toString( )
+    {
+        final StringBuilder sb = new StringBuilder( "ManagedRepository{" );
+        sb.append( "blocksRedeployments=" ).append( blocksRedeployments );
+        sb.append( ", releaseSchemes=" ).append( releaseSchemes );
+        sb.append( ", id='" ).append( id ).append( '\'' );
+        sb.append( ", name='" ).append( name ).append( '\'' );
+        sb.append( ", description='" ).append( description ).append( '\'' );
+        sb.append( ", type='" ).append( type ).append( '\'' );
+        sb.append( ", location='" ).append( location ).append( '\'' );
+        sb.append( ", scanned=" ).append( scanned );
+        sb.append( ", schedulingDefinition='" ).append( schedulingDefinition ).append( '\'' );
+        sb.append( ", index=" ).append( index );
+        sb.append( ", layout='" ).append( layout ).append( '\'' );
+        sb.append( '}' );
+        return sb.toString( );
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MavenRemoteRepository.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MavenRemoteRepository.java
new file mode 100644 (file)
index 0000000..3f05fb4
--- /dev/null
@@ -0,0 +1,168 @@
+package org.apache.archiva.rest.api.model.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.swagger.v3.oas.annotations.media.Schema;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Schema(name="MavenRemoteRepository",description = "A remote repository definition is used to pull artifacts from other repositories")
+public class MavenRemoteRepository extends Repository
+{
+    private static final long serialVersionUID = 5625043398766480265L;
+    String loginUser;
+    String loginPassword;
+    String checkPath;
+    Map<String,String> extraParameters = new TreeMap<>(  );
+    Map<String,String> requestHeader = new TreeMap<>(  );
+    long timeoutMs;
+
+    @Schema(name="login_user",description = "Username for login to the remote repository")
+    public String getLoginUser( )
+    {
+        return loginUser;
+    }
+
+    public void setLoginUser( String loginUser )
+    {
+        this.loginUser = loginUser;
+    }
+
+    @Schema(name="login_password",description = "Password for connecting to the remote repository")
+    public String getLoginPassword( )
+    {
+        return loginPassword;
+    }
+
+    public void setLoginPassword( String loginPassword )
+    {
+        this.loginPassword = loginPassword;
+    }
+
+    @Schema(name="check_path",description = "Path relative to the repository URL that is used to check of availability of the remote repository.")
+    public String getCheckPath( )
+    {
+        return checkPath;
+    }
+
+    public void setCheckPath( String checkPath )
+    {
+        this.checkPath = checkPath;
+    }
+
+    @Schema(name="extra_parameters", description = "Key-Value map with extra parameters sent to the remote repository")
+    public Map<String, String> getExtraParameters( )
+    {
+        return extraParameters;
+    }
+
+    public void setExtraParameters( Map<String, String> extraParameters )
+    {
+        this.extraParameters = new TreeMap<>( extraParameters );
+    }
+
+    public void addExtraParameter(String key, String value) {
+        this.extraParameters.put( key, value );
+    }
+
+    @Schema(name="request_header",description = "Key-Value map with request headers that are sent to the remote repository")
+    public Map<String, String> getRequestHeader( )
+    {
+        return requestHeader;
+    }
+
+    public void setRequestHeader( Map<String, String> requestHeader )
+    {
+        this.requestHeader = new TreeMap<>( requestHeader );
+    }
+
+    public void addRequestHeader(String headerName, String headerValue) {
+        this.requestHeader.put( headerName, headerValue );
+    }
+
+    @Schema(name="timeout_ms", description = "The time in milliseconds after that a request to the remote repository is aborted")
+    public long getTimeoutMs( )
+    {
+        return timeoutMs;
+    }
+
+    public void setTimeoutMs( long timeoutMs )
+    {
+        this.timeoutMs = timeoutMs;
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o ) return true;
+        if ( o == null || getClass( ) != o.getClass( ) ) return false;
+        if ( !super.equals( o ) ) return false;
+
+        MavenRemoteRepository that = (MavenRemoteRepository) o;
+
+        if ( timeoutMs != that.timeoutMs ) return false;
+        if ( loginUser != null ? !loginUser.equals( that.loginUser ) : that.loginUser != null ) return false;
+        if ( loginPassword != null ? !loginPassword.equals( that.loginPassword ) : that.loginPassword != null )
+            return false;
+        if ( checkPath != null ? !checkPath.equals( that.checkPath ) : that.checkPath != null ) return false;
+        if ( extraParameters != null ? !extraParameters.equals( that.extraParameters ) : that.extraParameters != null )
+            return false;
+        return requestHeader != null ? requestHeader.equals( that.requestHeader ) : that.requestHeader == null;
+    }
+
+    @Override
+    public int hashCode( )
+    {
+        int result = super.hashCode( );
+        result = 31 * result + ( loginUser != null ? loginUser.hashCode( ) : 0 );
+        result = 31 * result + ( loginPassword != null ? loginPassword.hashCode( ) : 0 );
+        result = 31 * result + ( checkPath != null ? checkPath.hashCode( ) : 0 );
+        result = 31 * result + ( extraParameters != null ? extraParameters.hashCode( ) : 0 );
+        result = 31 * result + ( requestHeader != null ? requestHeader.hashCode( ) : 0 );
+        result = 31 * result + (int) ( timeoutMs ^ ( timeoutMs >>> 32 ) );
+        return result;
+    }
+
+    @Override
+    public String toString( )
+    {
+        final StringBuilder sb = new StringBuilder( "RemoteRepository{" );
+        sb.append( "loginUser='" ).append( loginUser ).append( '\'' );
+        sb.append( ", loginPassword='" ).append( loginPassword ).append( '\'' );
+        sb.append( ", checkPath='" ).append( checkPath ).append( '\'' );
+        sb.append( ", extraParameters=" ).append( extraParameters );
+        sb.append( ", requestHeader=" ).append( requestHeader );
+        sb.append( ", timeOut=" ).append( timeoutMs );
+        sb.append( ", id='" ).append( id ).append( '\'' );
+        sb.append( ", name='" ).append( name ).append( '\'' );
+        sb.append( ", description='" ).append( description ).append( '\'' );
+        sb.append( ", type='" ).append( type ).append( '\'' );
+        sb.append( ", location='" ).append( location ).append( '\'' );
+        sb.append( ", scanned=" ).append( scanned );
+        sb.append( ", schedulingDefinition='" ).append( schedulingDefinition ).append( '\'' );
+        sb.append( ", index=" ).append( index );
+        sb.append( ", layout='" ).append( layout ).append( '\'' );
+        sb.append( '}' );
+        return sb.toString( );
+    }
+}
index c5e60dad863e06d988671a1e91e807d94d0f9e4e..95a286b319f39b99392f37bdaada2c1f7f92245d 100644 (file)
@@ -16,6 +16,24 @@ package org.apache.archiva.rest.api.model.v2;/*
  * under the License.
  */
 
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
 
 import javax.xml.bind.annotation.XmlRootElement;
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/Repository.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/Repository.java
new file mode 100644 (file)
index 0000000..ea4993d
--- /dev/null
@@ -0,0 +1,281 @@
+package org.apache.archiva.rest.api.model.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.
+ */
+
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.repository.ManagedRepository;
+import org.apache.archiva.repository.RemoteRepository;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Schema(description = "Repository data")
+public class Repository implements Serializable
+{
+    private static final long serialVersionUID = -4741025877287175182L;
+
+    public static final String CHARACTERISTIC_MANAGED = "managed";
+    public static final String CHARACTERISTIC_REMOTE = "remote";
+    public static final String CHARACTERISTIC_UNKNOWN = "unknown";
+
+    protected String id;
+    protected String name;
+    protected String description;
+    protected String type;
+    protected String characteristic;
+    protected String location;
+    protected boolean scanned;
+    protected String schedulingDefinition;
+    protected boolean index;
+    protected String layout;
+
+    public Repository( )
+    {
+    }
+
+    public static Repository of( org.apache.archiva.repository.Repository repository ) {
+        Repository newRepo = new Repository( );
+        newRepo.setId( repository.getId() );
+        newRepo.setName( repository.getName( ) );
+        newRepo.setDescription( repository.getDescription( ) );
+        newRepo.setLocation( repository.getLocation().toASCIIString() );
+        newRepo.setIndex( repository.hasIndex() );
+        newRepo.setLayout( repository.getLayout() );
+        newRepo.setType( repository.getType().name() );
+        newRepo.setScanned( repository.isScanned() );
+        newRepo.setSchedulingDefinition( repository.getSchedulingDefinition() );
+        if (repository instanceof RemoteRepository ) {
+            newRepo.setCharacteristic( CHARACTERISTIC_REMOTE );
+        } else if (repository instanceof ManagedRepository ) {
+            newRepo.setCharacteristic( CHARACTERISTIC_MANAGED );
+        } else {
+            newRepo.setCharacteristic( CHARACTERISTIC_UNKNOWN );
+        }
+        return newRepo;
+    }
+
+    public static Repository of( org.apache.archiva.repository.Repository repository, Locale locale ) {
+        Locale myLocale;
+        if (locale==null) {
+            myLocale = Locale.getDefault( );
+        } else {
+            myLocale = locale;
+        }
+        Repository newRepo = new Repository( );
+        newRepo.setId( repository.getId() );
+        newRepo.setName( repository.getName( myLocale ) );
+        newRepo.setDescription( repository.getDescription( myLocale ) );
+        newRepo.setLocation( repository.getLocation().toASCIIString() );
+        newRepo.setIndex( repository.hasIndex() );
+        newRepo.setLayout( repository.getLayout() );
+        newRepo.setType( repository.getType().name() );
+        newRepo.setScanned( repository.isScanned() );
+        newRepo.setSchedulingDefinition( repository.getSchedulingDefinition() );
+        if (repository instanceof RemoteRepository ) {
+            newRepo.setCharacteristic( CHARACTERISTIC_REMOTE );
+        } else if (repository instanceof ManagedRepository ) {
+            newRepo.setCharacteristic( CHARACTERISTIC_MANAGED );
+        } else {
+            newRepo.setCharacteristic( CHARACTERISTIC_UNKNOWN );
+        }
+        return newRepo;
+    }
+
+    @Schema(description = "Category of the repository. Either 'managed' or 'remote'.")
+    public String getCharacteristic( )
+    {
+        return characteristic;
+    }
+
+    public void setCharacteristic( String characteristic )
+    {
+        this.characteristic = characteristic;
+    }
+
+    @Schema(description = "Unique identifier of the repository")
+    public String getId( )
+    {
+        return id;
+    }
+
+    public void setId( String id )
+    {
+        this.id = id;
+    }
+
+    @Schema(description = "Display name of the repository")
+    public String getName( )
+    {
+        return name;
+    }
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    @Schema(description = "Description of the repository")
+    public String getDescription( )
+    {
+        return description;
+    }
+
+    public void setDescription( String description )
+    {
+        this.description = description;
+    }
+
+    @Schema(description = "Repository type")
+    public String getType( )
+    {
+        return type;
+    }
+
+    public void setType( String type )
+    {
+        this.type = type;
+    }
+
+    @Schema(description = "The location, where the repository data can be found")
+    public String getLocation( )
+    {
+        return location;
+    }
+
+    public void setLocation( String location )
+    {
+        this.location = location;
+    }
+
+    @Schema(description = "True, if this repository is scanned regularly")
+    public boolean isScanned( )
+    {
+        return scanned;
+    }
+
+    public void setScanned( boolean scanned )
+    {
+        this.scanned = scanned;
+    }
+
+    @Schema(name="scheduling_definition",description = "Definition of regular scheduled scan")
+    public String getSchedulingDefinition( )
+    {
+        return schedulingDefinition;
+    }
+
+    public void setSchedulingDefinition( String schedulingDefinition )
+    {
+        this.schedulingDefinition = schedulingDefinition;
+    }
+
+    @Schema(description = "True, if this is a indexed repository")
+    public boolean isIndex( )
+    {
+        return index;
+    }
+
+    public void setIndex( boolean index )
+    {
+        this.index = index;
+    }
+
+    @Schema(description = "Layout type is implementation specific")
+    public String getLayout( )
+    {
+        return layout;
+    }
+
+    public void setLayout( String layout )
+    {
+        this.layout = layout;
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o ) return true;
+        if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+        Repository that = (Repository) o;
+
+        if ( scanned != that.scanned ) return false;
+        if ( index != that.index ) return false;
+        if ( id != null ? !id.equals( that.id ) : that.id != null ) return false;
+        if ( name != null ? !name.equals( that.name ) : that.name != null ) return false;
+        if ( description != null ? !description.equals( that.description ) : that.description != null ) return false;
+        if ( type != null ? !type.equals( that.type ) : that.type != null ) return false;
+        if ( location != null ? !location.equals( that.location ) : that.location != null ) return false;
+        if ( schedulingDefinition != null ? !schedulingDefinition.equals( that.schedulingDefinition ) : that.schedulingDefinition != null )
+            return false;
+        return layout != null ? layout.equals( that.layout ) : that.layout == null;
+    }
+
+    @Override
+    public int hashCode( )
+    {
+        int result = id != null ? id.hashCode( ) : 0;
+        result = 31 * result + ( name != null ? name.hashCode( ) : 0 );
+        result = 31 * result + ( description != null ? description.hashCode( ) : 0 );
+        result = 31 * result + ( type != null ? type.hashCode( ) : 0 );
+        result = 31 * result + ( location != null ? location.hashCode( ) : 0 );
+        result = 31 * result + ( scanned ? 1 : 0 );
+        result = 31 * result + ( schedulingDefinition != null ? schedulingDefinition.hashCode( ) : 0 );
+        result = 31 * result + ( index ? 1 : 0 );
+        result = 31 * result + ( layout != null ? layout.hashCode( ) : 0 );
+        return result;
+    }
+
+    @Override
+    public String toString( )
+    {
+        final StringBuilder sb = new StringBuilder( "Repository{" );
+        sb.append( "id='" ).append( id ).append( '\'' );
+        sb.append( ", name='" ).append( name ).append( '\'' );
+        sb.append( ", description='" ).append( description ).append( '\'' );
+        sb.append( ", type='" ).append( type ).append( '\'' );
+        sb.append( ", location='" ).append( location ).append( '\'' );
+        sb.append( ", scanned=" ).append( scanned );
+        sb.append( ", schedulingDefinition='" ).append( schedulingDefinition ).append( '\'' );
+        sb.append( ", index=" ).append( index );
+        sb.append( ", layout='" ).append( layout ).append( '\'' );
+        sb.append( '}' );
+        return sb.toString( );
+    }
+}
index d550f27c97720f1a962bd21f44f7f0c07d65aaec..7eea247021200425614f30470cf6a0258e742a9e 100644 (file)
@@ -16,6 +16,24 @@ package org.apache.archiva.rest.api.model.v2;/*
  * under the License.
  */
 
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
 
 import javax.xml.bind.annotation.XmlRootElement;
@@ -33,7 +51,7 @@ public class RepositoryGroup implements Serializable
 {
     private static final long serialVersionUID = -7319687481737616081L;
     private String id;
-    private final List<String> repositories = new ArrayList<>(  );
+    private List<String> repositories = new ArrayList<>(  );
     private String location;
     MergeConfiguration mergeConfiguration;
 
@@ -77,8 +95,7 @@ public class RepositoryGroup implements Serializable
 
     public void setRepositories( List<String> repositories )
     {
-        this.repositories.clear();
-        this.repositories.addAll( repositories );
+        this.repositories = new ArrayList<>( repositories );
     }
 
     public void addRepository(String repositoryId) {
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryStatistics.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryStatistics.java
new file mode 100644 (file)
index 0000000..1417a19
--- /dev/null
@@ -0,0 +1,291 @@
+package org.apache.archiva.rest.api.model.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.
+ */
+
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.repository.scanner.RepositoryScanStatistics;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.time.Duration;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@XmlRootElement(name="repositoryStatistics")
+@Schema(name="RepositoryStatistics", description = "Statistics data")
+public class RepositoryStatistics implements Serializable
+{
+    private static final long serialVersionUID = 7943367882738452531L;
+
+    private OffsetDateTime scanEndTime;
+    private OffsetDateTime scanStartTime;
+    private long scanDurationMs;
+    private long totalArtifactCount;
+    private long totalArtifactFileSize;
+    private long totalFileCount;
+    private long totalGroupCount;
+    private long totalProjectCount;
+    private long newFileCount;
+    private Map<String, Long> totalCountForType = new TreeMap<>(  );
+    private Map<String, Long> customValues = new TreeMap<>(  );
+
+    public RepositoryStatistics( )
+    {
+    }
+
+    public static RepositoryStatistics of( org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics modelStats ) {
+        RepositoryStatistics newStats = new RepositoryStatistics( );
+        newStats.setScanStartTime( modelStats.getScanStartTime().toInstant().atOffset( ZoneOffset.UTC ) );
+        newStats.setScanEndTime( modelStats.getScanEndTime( ).toInstant( ).atOffset( ZoneOffset.UTC ) );
+        newStats.setNewFileCount( modelStats.getNewFileCount() );
+        newStats.setScanDurationMs( Duration.between( newStats.scanStartTime, newStats.scanEndTime ).toMillis() );
+        newStats.setTotalArtifactCount( modelStats.getTotalArtifactCount() );
+        newStats.setTotalArtifactFileSize( modelStats.getTotalArtifactFileSize() );
+        newStats.setTotalCountForType( modelStats.getTotalCountForType() );
+        newStats.setTotalFileCount( modelStats.getTotalFileCount() );
+        newStats.setTotalGroupCount( modelStats.getTotalGroupCount() );
+        newStats.setTotalProjectCount( modelStats.getTotalProjectCount() );
+        for (String key : modelStats.getAvailableCustomValues()) {
+            newStats.addCustomValue( key, modelStats.getCustomValue( key ) );
+        }
+        return newStats;
+    }
+
+    public static RepositoryStatistics of( RepositoryScanStatistics scanStatistics ) {
+        RepositoryStatistics newStats = new RepositoryStatistics( );
+        newStats.setScanStartTime( scanStatistics.getWhenGathered().toInstant().atOffset( ZoneOffset.UTC ) );
+        newStats.setScanEndTime( OffsetDateTime.now(ZoneOffset.UTC) );
+        newStats.setNewFileCount( scanStatistics.getNewFileCount() );
+        newStats.setScanDurationMs( Duration.between( newStats.scanStartTime, newStats.scanEndTime ).toMillis() );
+        newStats.setTotalArtifactCount( scanStatistics.getTotalFileCount() );
+        newStats.setTotalArtifactFileSize( scanStatistics.getTotalSize() );
+        newStats.setTotalFileCount( scanStatistics.getTotalFileCount() );
+        newStats.setTotalGroupCount( 0 );
+        newStats.setTotalProjectCount( 0 );
+        return newStats;
+    }
+
+    @Schema(name="scan_end_time", description = "Date and time when the last scan finished")
+    public OffsetDateTime getScanEndTime( )
+    {
+        return scanEndTime;
+    }
+
+    public void setScanEndTime( OffsetDateTime scanEndTime )
+    {
+        this.scanEndTime = scanEndTime;
+    }
+
+    @Schema( name = "scan_start_time", description = "Date and time when the last scan started" )
+    public OffsetDateTime getScanStartTime( )
+    {
+        return scanStartTime;
+    }
+
+    public void setScanStartTime( OffsetDateTime scanStartTime )
+    {
+        this.scanStartTime = scanStartTime;
+    }
+
+    @Schema(name="total_artifact_count", description = "The number of artifacts scanned")
+    public long getTotalArtifactCount( )
+    {
+        return totalArtifactCount;
+    }
+
+    public void setTotalArtifactCount( long totalArtifactCount )
+    {
+        this.totalArtifactCount = totalArtifactCount;
+    }
+
+    @Schema(name="total_artifact_file_size", description = "The cumulative size of all files scanned")
+    public long getTotalArtifactFileSize( )
+    {
+        return totalArtifactFileSize;
+    }
+
+    public void setTotalArtifactFileSize( long totalArtifactFileSize )
+    {
+        this.totalArtifactFileSize = totalArtifactFileSize;
+    }
+
+    @Schema(name="total_file_count", description = "The total number of files scanned")
+    public long getTotalFileCount( )
+    {
+        return totalFileCount;
+    }
+
+    public void setTotalFileCount( long totalFileCount )
+    {
+        this.totalFileCount = totalFileCount;
+    }
+
+    @Schema(name="total_group_count", description = "The number of groups scanned")
+    public long getTotalGroupCount( )
+    {
+        return totalGroupCount;
+    }
+
+    public void setTotalGroupCount( long totalGroupCount )
+    {
+        this.totalGroupCount = totalGroupCount;
+    }
+
+    @Schema(name="total_project_count", description = "The number of projects scanned")
+    public long getTotalProjectCount( )
+    {
+        return totalProjectCount;
+    }
+
+    public void setTotalProjectCount( long totalProjectCount )
+    {
+        this.totalProjectCount = totalProjectCount;
+    }
+
+    @Schema(name="new_file_count", description = "Number of files registered as new")
+    public long getNewFileCount( )
+    {
+        return newFileCount;
+    }
+
+    public void setNewFileCount( long newFileCount )
+    {
+        this.newFileCount = newFileCount;
+    }
+
+    @Schema(name="scan_duration_ms", description = "The duration of the last scan in ms")
+    public long getScanDurationMs( )
+    {
+        return scanDurationMs;
+    }
+
+    public void setScanDurationMs( long scanDurationMs )
+    {
+        this.scanDurationMs = scanDurationMs;
+    }
+
+    @Schema(name="total_count_for_type", description = "File counts partitioned by file types")
+    public Map<String, Long> getTotalCountForType( )
+    {
+        return totalCountForType;
+    }
+
+    public void setTotalCountForType( Map<String, Long> totalCountForType )
+    {
+        this.totalCountForType = new TreeMap<>( totalCountForType );
+    }
+
+    public void addTotalCountForType( String type, Long value )
+    {
+        this.totalCountForType.put( type, value );
+    }
+
+    @Schema(name="custom_values", description = "Custom statistic values")
+    public Map<String, Long> getCustomValues( )
+    {
+        return customValues;
+    }
+
+    public void setCustomValues( Map<String, Long> customValues )
+    {
+        this.customValues = new TreeMap<>(  customValues );
+    }
+
+    public void addCustomValue(String type, Long value) {
+        this.customValues.put( type, value );
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o ) return true;
+        if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+        RepositoryStatistics that = (RepositoryStatistics) o;
+
+        if ( scanDurationMs != that.scanDurationMs ) return false;
+        if ( totalArtifactCount != that.totalArtifactCount ) return false;
+        if ( totalArtifactFileSize != that.totalArtifactFileSize ) return false;
+        if ( totalFileCount != that.totalFileCount ) return false;
+        if ( totalGroupCount != that.totalGroupCount ) return false;
+        if ( totalProjectCount != that.totalProjectCount ) return false;
+        if ( newFileCount != that.newFileCount ) return false;
+        if ( scanEndTime != null ? !scanEndTime.equals( that.scanEndTime ) : that.scanEndTime != null ) return false;
+        if ( scanStartTime != null ? !scanStartTime.equals( that.scanStartTime ) : that.scanStartTime != null )
+            return false;
+        if ( !totalCountForType.equals( that.totalCountForType ) ) return false;
+        return customValues.equals( that.customValues );
+    }
+
+    @Override
+    public int hashCode( )
+    {
+        int result = scanEndTime != null ? scanEndTime.hashCode( ) : 0;
+        result = 31 * result + ( scanStartTime != null ? scanStartTime.hashCode( ) : 0 );
+        result = 31 * result + (int) ( scanDurationMs ^ ( scanDurationMs >>> 32 ) );
+        result = 31 * result + (int) ( totalArtifactCount ^ ( totalArtifactCount >>> 32 ) );
+        result = 31 * result + (int) ( totalArtifactFileSize ^ ( totalArtifactFileSize >>> 32 ) );
+        result = 31 * result + (int) ( totalFileCount ^ ( totalFileCount >>> 32 ) );
+        result = 31 * result + (int) ( totalGroupCount ^ ( totalGroupCount >>> 32 ) );
+        result = 31 * result + (int) ( totalProjectCount ^ ( totalProjectCount >>> 32 ) );
+        result = 31 * result + (int) ( newFileCount ^ ( newFileCount >>> 32 ) );
+        result = 31 * result + totalCountForType.hashCode( );
+        result = 31 * result + customValues.hashCode( );
+        return result;
+    }
+
+    @Override
+    public String toString( )
+    {
+        final StringBuilder sb = new StringBuilder( "RepositoryStatistics{" );
+        sb.append( "scanEndTime=" ).append( scanEndTime );
+        sb.append( ", scanStartTime=" ).append( scanStartTime );
+        sb.append( ", scanDurationMs=" ).append( scanDurationMs );
+        sb.append( ", totalArtifactCount=" ).append( totalArtifactCount );
+        sb.append( ", totalArtifactFileSize=" ).append( totalArtifactFileSize );
+        sb.append( ", totalFileCount=" ).append( totalFileCount );
+        sb.append( ", totalGroupCount=" ).append( totalGroupCount );
+        sb.append( ", totalProjectCount=" ).append( totalProjectCount );
+        sb.append( ", newFileCount=" ).append( newFileCount );
+        sb.append( '}' );
+        return sb.toString( );
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanStatus.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanStatus.java
new file mode 100644 (file)
index 0000000..9800bbb
--- /dev/null
@@ -0,0 +1,137 @@
+package org.apache.archiva.rest.api.model.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.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
+import org.apache.archiva.scheduler.repository.model.RepositoryTask;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="ScanStatus", description = "Status of repository scan tasks")
+public class ScanStatus implements Serializable
+{
+    private boolean scanRunning = false;
+    private int scanQueued = 0;
+    private boolean indexRunning = false;
+    private int indexQueued = 0;
+    private List<IndexingTask> indexingQueue = new ArrayList<>(  );
+    private List<ScanTask> scanQueue = new ArrayList<>(  );
+
+    public ScanStatus( )
+    {
+    }
+
+    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 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" )
+    public boolean isScanRunning( )
+    {
+        return scanRunning;
+    }
+
+    public void setScanRunning( boolean scanRunning )
+    {
+        this.scanRunning = scanRunning;
+    }
+
+    @Schema(name ="scan_queued", description = "Number of scans in the task queue")
+    public int getScanQueued( )
+    {
+        return scanQueued;
+    }
+
+    public void setScanQueued( int scanQueued )
+    {
+        this.scanQueued = scanQueued;
+    }
+
+    @Schema(name="index_running", description = "True, if there is a index task currently running")
+    public boolean isIndexRunning( )
+    {
+        return indexRunning;
+    }
+
+    public void setIndexRunning( boolean indexRunning )
+    {
+        this.indexRunning = indexRunning;
+    }
+
+    @Schema(name="index_queued", description = "Number of queued index tasks")
+    public int getIndexQueued( )
+    {
+        return indexQueued;
+    }
+
+    public void setIndexQueued( int indexQueued )
+    {
+        this.indexQueued = indexQueued;
+    }
+
+    @Schema( name = "indexing_queue", description = "List of indexing tasks waiting for execution" )
+    public List<IndexingTask> getIndexingQueue( )
+    {
+        return indexingQueue;
+    }
+
+    public void setIndexingQueue( List<IndexingTask> indexingQueue )
+    {
+        this.indexingQueue = new ArrayList<>( indexingQueue );
+    }
+
+    @Schema(name="scan_queue", description = "List of scan tasks waiting for execution")
+    public List<ScanTask> getScanQueue( )
+    {
+        return scanQueue;
+    }
+
+    public void setScanQueue( List<ScanTask> scanQueue )
+    {
+        this.scanQueue = new ArrayList<>( scanQueue );
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanTask.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanTask.java
new file mode 100644 (file)
index 0000000..96aa96f
--- /dev/null
@@ -0,0 +1,156 @@
+package org.apache.archiva.rest.api.model.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.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.scheduler.repository.model.RepositoryTask;
+
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="ScanTask", description = "Repository scan task information")
+public class ScanTask implements Serializable
+{
+    private static final long serialVersionUID = -681163357370848098L;
+    private String repositoryId="";
+    private boolean updateRelatedArtifacts;
+    private boolean fullRepository;
+    private boolean running = false;
+    private String resource = "";
+    private long maxExecutionTimeMs = 0;
+
+    public static ScanTask of( RepositoryTask repositoryTask ) {
+        ScanTask scanTask = new ScanTask( );
+        scanTask.setFullRepository( repositoryTask.isScanAll());
+        scanTask.setUpdateRelatedArtifacts( repositoryTask.isUpdateRelatedArtifacts() );
+        scanTask.setResource( repositoryTask.getResourceFile( ).toString( ) );
+        scanTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTime() );
+        scanTask.setRepositoryId( repositoryTask.getRepositoryId( ) );
+        return scanTask;
+    }
+
+    @Schema(name="repository_id", description = "Identifier of the repository, this task is running on")
+    public String getRepositoryId( )
+    {
+        return repositoryId;
+    }
+
+    public void setRepositoryId( String repositoryId )
+    {
+        this.repositoryId = repositoryId==null?"":repositoryId;
+    }
+
+    @Schema(name="update_related_artifacts", description = "True, if related artifacts are updated too.")
+    public boolean isUpdateRelatedArtifacts( )
+    {
+        return updateRelatedArtifacts;
+    }
+
+    public void setUpdateRelatedArtifacts( boolean updateRelatedArtifacts )
+    {
+        this.updateRelatedArtifacts = updateRelatedArtifacts;
+    }
+
+    @Schema(name="full_repository",description = "True, if this is a full repository scan")
+    public boolean isFullRepository( )
+    {
+        return fullRepository;
+    }
+
+    public void setFullRepository( boolean fullRepository )
+    {
+        this.fullRepository = fullRepository;
+    }
+
+    @Schema(name="running", description = "True, if this task is currently running")
+    public boolean isRunning( )
+    {
+        return running;
+    }
+
+    public void setRunning( boolean running )
+    {
+        this.running = running;
+    }
+
+    @Schema(name="resource",description = "Name of the resource to update")
+    public String getResource( )
+    {
+        return resource;
+    }
+
+    public void setResource( String resource )
+    {
+        this.resource = resource==null?"":resource;
+    }
+
+    @Schema(name="max_excecution_time_ms",description = "Maximum execution time in ms")
+    public long getMaxExecutionTimeMs( )
+    {
+        return maxExecutionTimeMs;
+    }
+
+    public void setMaxExecutionTimeMs( long maxExecutionTimeMs )
+    {
+        this.maxExecutionTimeMs = maxExecutionTimeMs;
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o ) return true;
+        if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+        ScanTask scanTask = (ScanTask) o;
+
+        if ( updateRelatedArtifacts != scanTask.updateRelatedArtifacts ) return false;
+        if ( fullRepository != scanTask.fullRepository ) 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 + ( fullRepository ? 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( fullRepository );
+        sb.append( ", running=" ).append( running );
+        sb.append( ", resource='" ).append( resource ).append( '\'' );
+        sb.append( ", maxExecutionTimeMs=" ).append( maxExecutionTimeMs );
+        sb.append( '}' );
+        return sb.toString( );
+    }
+}
index 1204e66e2c886171a3c72c834ed1d50896aae594..efe02a4f398415f7ba347ac296ce1fa6308553bd 100644 (file)
@@ -16,6 +16,24 @@ package org.apache.archiva.rest.api.model.v2;/*
  * under the License.
  */
 
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
 import org.apache.archiva.admin.model.beans.RedbackRuntimeConfiguration;
 
@@ -35,9 +53,9 @@ public class SecurityConfiguration implements Serializable
 {
     private static final long serialVersionUID = -4186866365979053029L;
 
-    private final List<String> activeUserManagers = new ArrayList<>(  );
-    private final List<String> activeRbacManagers = new ArrayList<>(  );
-    private final Map<String,String> properties = new TreeMap<>(  );
+    private List<String> activeUserManagers = new ArrayList<>(  );
+    private List<String> activeRbacManagers = new ArrayList<>(  );
+    private Map<String,String> properties = new TreeMap<>(  );
     private boolean userCacheEnabled=false;
     private boolean ldapActive=false;
 
@@ -64,8 +82,7 @@ public class SecurityConfiguration implements Serializable
 
     public void setActiveUserManagers( List<String> activeUserManagers )
     {
-        this.activeUserManagers.clear();
-        this.activeUserManagers.addAll( activeUserManagers );
+        this.activeUserManagers = new ArrayList<>( activeUserManagers );
     }
 
     public void addSelectedUserManager(String userManager) {
@@ -80,8 +97,7 @@ public class SecurityConfiguration implements Serializable
 
     public void setActiveRbacManagers( List<String> activeRbacManagers )
     {
-        this.activeRbacManagers.clear();
-        this.activeRbacManagers.addAll( activeRbacManagers );
+        this.activeRbacManagers = new ArrayList<>( activeRbacManagers );
     }
 
     public void addSelectedRbacManager(String rbacManager) {
@@ -96,8 +112,7 @@ public class SecurityConfiguration implements Serializable
 
     public void setProperties( Map<String, String> properties )
     {
-        this.properties.clear();
-        this.properties.putAll( properties );
+        this.properties = new TreeMap<>( properties );
     }
 
     @Schema(name="user_cache_enabled", description = "True, if the user cache is active. It caches data from user backend.")
@@ -156,7 +171,7 @@ public class SecurityConfiguration implements Serializable
         sb.append( "active_user_managers=" ).append( activeUserManagers );
         sb.append( ", active_rbac_managers=" ).append( activeRbacManagers );
         sb.append( ", properties=" ).append( properties );
-        sb.append( ", user_cache_nabled=" ).append( userCacheEnabled );
+        sb.append( ", user_cache_enabled=" ).append( userCacheEnabled );
         sb.append( ", ldap_active=" ).append( ldapActive );
         sb.append( '}' );
         return sb.toString( );
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/ArtifactCleanupInfo.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/ArtifactCleanupInfo.java
new file mode 100644 (file)
index 0000000..879bb8b
--- /dev/null
@@ -0,0 +1,83 @@
+package org.apache.archiva.rest.api.model.v2.repository;/*
+ * 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.
+ */
+
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
+
+import java.time.Period;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="ArtifactCleanupInfo",description = "Information for artifact cleanup feature of repository")
+public class ArtifactCleanupInfo
+{
+    boolean deleteReleasedSnapshots;
+    Period retentionPeriod;
+    int retentionCount;
+
+    @Schema(name="delete_released_snapshots",description = "True, if snapshots are deleted after a release was published")
+    public boolean isDeleteReleasedSnapshots( )
+    {
+        return deleteReleasedSnapshots;
+    }
+
+    public void setDeleteReleasedSnapshots( boolean deleteReleasedSnapshots )
+    {
+        this.deleteReleasedSnapshots = deleteReleasedSnapshots;
+    }
+
+    @Schema(name="retention_period",description = "Time, after that snapshot artifacts are marked for deletion")
+    public Period getRetentionPeriod( )
+    {
+        return retentionPeriod;
+    }
+
+    public void setRetentionPeriod( Period retentionPeriod )
+    {
+        this.retentionPeriod = retentionPeriod;
+    }
+
+    @Schema(name="retention_count",description = "Maximum number of snapshot artifacts to keep")
+    public int getRetentionCount( )
+    {
+        return retentionCount;
+    }
+
+    public void setRetentionCount( int retentionCount )
+    {
+        this.retentionCount = retentionCount;
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/IndexCreationInfo.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/IndexCreationInfo.java
new file mode 100644 (file)
index 0000000..ebc506b
--- /dev/null
@@ -0,0 +1,85 @@
+package org.apache.archiva.rest.api.model.v2.repository;/*
+ * 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.
+ */
+
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.repository.Repository;
+import org.apache.archiva.repository.storage.StorageAsset;
+
+import java.net.URI;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="IndexCreationInfo",description = "Information about index creation feature of repositories")
+public class IndexCreationInfo
+{
+    private boolean skipPackedIndexCreation = false;
+    private String indexPath;
+    private String packedIndexPath;
+
+    @Schema(name="skip_packed_index_creation",description = "True, if the packed index will not be created")
+    public boolean isSkipPackedIndexCreation( )
+    {
+        return skipPackedIndexCreation;
+    }
+
+    public void setSkipPackedIndexCreation( boolean skipPackedIndexCreation )
+    {
+        this.skipPackedIndexCreation = skipPackedIndexCreation;
+    }
+
+    @Schema(name="index_path",description = "Path to the index directory relative to the repository base directory")
+    public String getIndexPath( )
+    {
+        return indexPath;
+    }
+
+    public void setIndexPath( String indexPath )
+    {
+        this.indexPath = indexPath;
+    }
+
+    @Schema(name="packed_index_path",description = "Path to the packed index directory relative to the repository base directory")
+    public String getPackedIndexPath( )
+    {
+        return packedIndexPath;
+    }
+
+    public void setPackedIndexPath( String packedIndexPath )
+    {
+        this.packedIndexPath = packedIndexPath;
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/RemoteIndexInfo.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/RemoteIndexInfo.java
new file mode 100644 (file)
index 0000000..c7dedc5
--- /dev/null
@@ -0,0 +1,71 @@
+package org.apache.archiva.rest.api.model.v2.repository;/*
+ * 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.
+ */
+
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
+
+import java.net.URI;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="RemoteIndexInfo",description = "Information about remote indexes")
+public class RemoteIndexInfo
+{
+    private boolean downloadRemoteIndex = false;
+    private String indexUri;
+
+    @Schema(name="download_remote_index",description = "True, if the index will be downloaded from the remote repository")
+    public boolean isDownloadRemoteIndex( )
+    {
+        return downloadRemoteIndex;
+    }
+
+    public void setDownloadRemoteIndex( boolean downloadRemoteIndex )
+    {
+        this.downloadRemoteIndex = downloadRemoteIndex;
+    }
+
+    @Schema(name="index_uri", description = "The URI that specifies the path to the remote index")
+    public String getIndexUri( )
+    {
+        return indexUri;
+    }
+
+    public void setIndexUri( String indexUri )
+    {
+        this.indexUri = indexUri;
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/StagingInfo.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/StagingInfo.java
new file mode 100644 (file)
index 0000000..1014d9f
--- /dev/null
@@ -0,0 +1,70 @@
+package org.apache.archiva.rest.api.model.v2.repository;/*
+ * 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.
+ */
+
+/*
+ * 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.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.repository.ManagedRepository;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="StagingInfo",description = "Information about staging feature of a repository")
+public class StagingInfo
+{
+    private String stagingRepository;
+    private boolean stageRepoNeeded;
+
+    @Schema(name="staging_repo",description = "The repository id of the staging repository")
+    public String getStagingRepository( )
+    {
+        return stagingRepository;
+    }
+
+    public void setStagingRepository( String stagingRepository )
+    {
+        this.stagingRepository = stagingRepository;
+    }
+
+    @Schema(name="stage_repo_needed",description = "True, if this repository needs a staging repository")
+    public boolean isStageRepoNeeded( )
+    {
+        return stageRepoNeeded;
+    }
+
+    public void setStageRepoNeeded( boolean stageRepoNeeded )
+    {
+        this.stageRepoNeeded = stageRepoNeeded;
+    }
+}
index 208f24f09eddb9157c01016facdc4dba788b4da1..9941e832e7c0a8dcfde2e45315bba0d3ee89372e 100644 (file)
@@ -86,7 +86,7 @@ public interface ManagedRepositoriesService
     @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
     @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
     @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
-    ActionStatus updateManagedRepository( ManagedRepository managedRepository )
+    Boolean updateManagedRepository( ManagedRepository managedRepository )
         throws ArchivaRestServiceException;
 
     /**
index c2ac99059fc58a33c914c8dbf09db7cbe19c06ba..3aabbe91f2416d24d38100ac6712bad413739c22 100644 (file)
@@ -1,4 +1,5 @@
-package org.apache.archiva.rest.api.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
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/Configuration.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/Configuration.java
deleted file mode 100644 (file)
index e0b6357..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-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
- * 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.
- */
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-public interface Configuration
-{
-    String DEFAULT_PAGE_LIMIT = "10";
-}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/MavenManagedRepositoryService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/MavenManagedRepositoryService.java
new file mode 100644 (file)
index 0000000..cf1b057
--- /dev/null
@@ -0,0 +1,302 @@
+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
+ * 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.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.headers.Header;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.redback.authorization.RedbackAuthorization;
+import org.apache.archiva.rest.api.model.v2.FileInfo;
+import org.apache.archiva.rest.api.model.v2.MavenManagedRepository;
+import org.apache.archiva.security.common.ArchivaRoleConstants;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.apache.archiva.rest.api.services.v2.RestConfiguration.DEFAULT_PAGE_LIMIT;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Schema( name = "ManagedRepositoryService", description = "Managing and configuration of managed repositories" )
+@Path( "repositories/maven/managed" )
+@Tag(name = "v2")
+@Tag(name = "v2/Repositories")
+public interface MavenManagedRepositoryService
+{
+    @Path( "" )
+    @GET
+    @Produces( {APPLICATION_JSON} )
+    @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+    @Operation( summary = "Returns all managed repositories.",
+        parameters = {
+            @Parameter( name = "q", description = "Search term" ),
+            @Parameter( name = "offset", description = "The offset of the first element returned" ),
+            @Parameter( name = "limit", description = "Maximum number of items to return in the response" ),
+            @Parameter( name = "orderBy", description = "List of attribute used for sorting (key, value)" ),
+            @Parameter( name = "order", description = "The sort order. Either ascending (asc) or descending (desc)" )
+        },
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the list could be returned",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = PagedResult.class ) )
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    PagedResult<MavenManagedRepository> getManagedRepositories(
+        @QueryParam( "q" ) @DefaultValue( "" ) String searchTerm,
+        @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
+        @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
+        @QueryParam( "orderBy" ) @DefaultValue( "id" ) List<String> orderBy,
+        @QueryParam( "order" ) @DefaultValue( "asc" ) String order )
+        throws ArchivaRestServiceException;
+
+
+    @Path( "{id}" )
+    @GET
+    @Produces( {MediaType.APPLICATION_JSON} )
+    @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+    @Operation( summary = "Returns the managed repository with the given id.",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the managed repository could be returned",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    MavenManagedRepository getManagedRepository( @PathParam( "id" ) String repositoryId )
+        throws ArchivaRestServiceException;
+
+
+    @Path( "{id}" )
+    @DELETE
+    @Produces( {MediaType.APPLICATION_JSON} )
+    @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+    @Operation( summary = "Deletes the managed repository with the given id.",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the managed repository could be returned"
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    Response deleteManagedRepository( @PathParam( "id" ) String repositoryId,
+                                      @QueryParam( "deleteContent" ) boolean deleteContent )
+        throws ArchivaRestServiceException;
+
+
+    @Path( "" )
+    @POST
+    @Consumes( {MediaType.APPLICATION_JSON} )
+    @Produces( {MediaType.APPLICATION_JSON} )
+    @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+    @Operation( summary = "Creates the managed repository",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "201",
+                description = "If the managed repository could be created",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
+            ),
+            @ApiResponse( responseCode = "303", description = "The repository exists already",
+                headers = {
+                    @Header( name = "Location", description = "The URL of existing repository ", schema = @Schema( type = "string" ) )
+                }
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "422", description = "The body data is not valid",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    MavenManagedRepository addManagedRepository( MavenManagedRepository managedRepository )
+        throws ArchivaRestServiceException;
+
+
+    @Path( "{id}" )
+    @PUT
+    @Consumes( {MediaType.APPLICATION_JSON} )
+    @Produces( {MediaType.APPLICATION_JSON} )
+    @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+    @Operation( summary = "Updates the managed repository with the given id",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the managed repository could be updated",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "422", description = "The body data is not valid",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    MavenManagedRepository updateManagedRepository( MavenManagedRepository managedRepository )
+        throws ArchivaRestServiceException;
+
+
+    @Path( "{id}/files/{filePath: .+}" )
+    @GET
+    @Produces( {MediaType.APPLICATION_JSON} )
+    @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+    @Operation( summary = "Returns the status of a given file in the repository",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the file status is returned",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = FileInfo.class ) )
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the file does not exist.",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    FileInfo getFileStatus( @PathParam( "id" ) String repositoryId, @PathParam( "filePath" ) String fileLocation )
+        throws ArchivaRestServiceException;
+
+
+    @Path ("{id}/content/{namespace}/{projectId}/{version}")
+    @DELETE
+    @Produces ({ MediaType.APPLICATION_JSON })
+    @RedbackAuthorization (noPermission = true)
+    @Operation( summary = "Removes a version tree in the repository",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the deletion was successful"
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete in repositories",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the version does not exist.",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    Response removeProjectVersion( @PathParam ( "id" ) String repositoryId,
+                                       @PathParam ( "namespace" ) String namespace, @PathParam ( "projectId" ) String projectId,
+                                       @PathParam ( "version" ) String version )
+        throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+
+
+    @Path ( "{id}/content/{namespace}/{projectId}" )
+    @DELETE
+    @Produces ({ MediaType.APPLICATION_JSON })
+    @RedbackAuthorization (noPermission = true)
+    @Operation( summary = "Removes a project tree in the repository",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the deletion was successful"
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete in repositories",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the project does not exist.",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    Response deleteProject( @PathParam ("id") String repositoryId, @PathParam ( "namespace" ) String namespace, @PathParam ("projectId") String projectId )
+        throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+
+    @Path ( "{id}/content/{namespace}" )
+    @DELETE
+    @Produces ({ MediaType.APPLICATION_JSON })
+    @RedbackAuthorization (noPermission = true)
+    @Operation( summary = "Removes a namespace tree in the repository",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the deletion was successful"
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete namespaces in repositories",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the namespace does not exist.",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    Response deleteNamespace( @PathParam ("id") String repositoryId, @PathParam ( "namespace" ) String namespace )
+        throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+
+}
index 08ff59e148973764e0e29739571f28da401afb8e..8a5b6eaeb0d7ce0849998274afa26f743dc8ab0e 100644 (file)
@@ -45,7 +45,7 @@ import javax.ws.rs.core.Response;
 import java.util.List;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static org.apache.archiva.rest.api.services.v2.Configuration.DEFAULT_PAGE_LIMIT;
+import static org.apache.archiva.rest.api.services.v2.RestConfiguration.DEFAULT_PAGE_LIMIT;
 
 /**
  * Endpoint for repository groups that combine multiple repositories into a single virtual repository.
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryService.java
new file mode 100644 (file)
index 0000000..8092ac7
--- /dev/null
@@ -0,0 +1,330 @@
+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
+ * 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.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.redback.authorization.RedbackAuthorization;
+import org.apache.archiva.rest.api.model.v2.Artifact;
+import org.apache.archiva.rest.api.model.v2.ArtifactTransferRequest;
+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.security.common.ArchivaRoleConstants;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.apache.archiva.rest.api.services.v2.RestConfiguration.DEFAULT_PAGE_LIMIT;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Path( "repositories" )
+@Tag(name = "v2")
+@Tag(name = "v2/Repositories")
+@Schema(name="RepositoryService",description = "Manage repositories of all types")
+public interface RepositoryService
+{
+
+    @Path( "" )
+    @GET
+    @Produces( {APPLICATION_JSON} )
+    @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+    @Operation( summary = "Returns all managed repositories.",
+        parameters = {
+            @Parameter( name = "q", description = "Search term" ),
+            @Parameter( name = "offset", description = "The offset of the first element returned" ),
+            @Parameter( name = "limit", description = "Maximum number of items to return in the response" ),
+            @Parameter( name = "orderBy", description = "List of attribute used for sorting (key, value)" ),
+            @Parameter( name = "order", description = "The sort order. Either ascending (asc) or descending (desc)" ),
+            @Parameter( name = "locale", description = "The locale for name and description" )
+        },
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the list could be returned",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = PagedResult.class ) )
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    PagedResult<Repository> getRepositories( @QueryParam( "q" ) @DefaultValue( "" ) String searchTerm,
+                                             @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
+                                             @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
+                                             @QueryParam( "orderBy" ) @DefaultValue( "id" ) List<String> orderBy,
+                                             @QueryParam( "order" ) @DefaultValue( "asc" ) String order,
+                                             @QueryParam( "locale" ) String localeString) throws ArchivaRestServiceException;
+
+    @Path( "managed/{id}/statistics" )
+    @GET
+    @Produces( {APPLICATION_JSON} )
+    @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+    @Operation( summary = "Returns repository statistic data.",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the statistics could be returned",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryStatistics.class ) )
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The repository does not exist",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    RepositoryStatistics getManagedRepositoryStatistics( @PathParam( "id" ) String repositoryId )
+        throws ArchivaRestServiceException;
+
+    @Path ("managed/{id}/scan/schedule")
+    @POST
+    @Produces ({ APPLICATION_JSON })
+    @Consumes({ APPLICATION_JSON })
+    @RedbackAuthorization (permissions = ArchivaRoleConstants.OPERATION_RUN_INDEXER)
+    @Operation( summary = "Returns repository statistic data.",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the statistics could be returned"
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The repository does not exist",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    Response scheduleRepositoryScan( @PathParam ("id") String repositoryId,
+                                     @QueryParam ("fullScan") boolean fullScan )
+        throws ArchivaRestServiceException;
+
+
+    /**
+     * scan directories
+     * @since 1.4-M3
+     */
+    @Path ("managed/{id}/scan/now")
+    @POST
+    @Produces ({ APPLICATION_JSON })
+    @Consumes({ APPLICATION_JSON })
+    @RedbackAuthorization (permissions = ArchivaRoleConstants.OPERATION_RUN_INDEXER)
+    @Operation( summary = "Runs a repository scan instantly and waits for the response.",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the statistics could be returned",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryStatistics.class ) )
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The repository does not exist",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    RepositoryStatistics scanRepositoryImmediately( @PathParam ("id") String repositoryId )
+        throws ArchivaRestServiceException;
+
+
+    /**
+     * Returns the scan status of the given repository
+     * @param repositoryId the repository identifier
+     * @return the status
+     * @throws ArchivaRestServiceException
+     * @since 3.0
+     */
+    @Path ("managed/{id}/scan/status")
+    @GET
+    @Produces ({ APPLICATION_JSON })
+    @RedbackAuthorization (permissions = ArchivaRoleConstants.OPERATION_RUN_INDEXER)
+    @Operation( summary = "Returns status of running and scheduled scans.",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the status could be returned",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ScanStatus.class ) )
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The repository does not exist",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    ScanStatus getScanStatus( @PathParam ("id") String repositoryId )
+        throws ArchivaRestServiceException;
+
+    @Path ("managed/{id}/scan")
+    @DELETE
+    @Produces ({ APPLICATION_JSON })
+    @RedbackAuthorization (permissions = ArchivaRoleConstants.OPERATION_RUN_INDEXER)
+    @Operation( summary = "Removes a scan task from the queue.",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the task was removed successfully"
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The repository does not exist",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    Response removeScanningTaskFromQueue( @PathParam ("id") String repositoryId )
+        throws ArchivaRestServiceException;
+
+    /**
+     * permissions are checked in impl
+     * will copy an artifact from the source repository to the target repository
+     */
+    @Path ("managed/{id}/artifact/copy")
+    @POST
+    @Produces({APPLICATION_JSON})
+    @Consumes({ APPLICATION_JSON })
+    @RedbackAuthorization (noPermission = true)
+    @Operation( summary = "Copies a artifact between repositories.",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the artifact was copied"
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The repository does not exist, or if the artifact was not found",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    Response copyArtifact( ArtifactTransferRequest artifactTransferRequest )
+        throws ArchivaRestServiceException;
+
+    @Path ("managed/{id}/index/download/start")
+    @POST
+    @Produces ({ APPLICATION_JSON })
+    @Consumes({ APPLICATION_JSON })
+    @RedbackAuthorization (permissions = ArchivaRoleConstants.OPERATION_RUN_INDEXER)
+    @Operation( summary = "Schedules a task for remote index download.",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the task was scheduled"
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The repository does not exist",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    Response scheduleDownloadRemoteIndex( @PathParam ("id") String repositoryId,
+                                              @QueryParam ("now") boolean now,
+                                              @QueryParam ("fullDownload") boolean fullDownload )
+        throws ArchivaRestServiceException;
+
+
+    @Path ("managed/{id}/artifact")
+    @DELETE
+    @Consumes ({ APPLICATION_JSON })
+    @RedbackAuthorization (noPermission = true)
+    @Operation( summary = "Deletes a artifact in the repository.",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the artifact was deleted"
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+            @ApiResponse( responseCode = "404", description = "The repository or the artifact does not exist",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    Response deleteArtifact( Artifact artifact )
+        throws ArchivaRestServiceException;
+
+    @Path ("index_downloads")
+    @GET
+    @Produces ({ APPLICATION_JSON })
+    @RedbackAuthorization (noPermission = true)
+    @Operation( summary = "Returns a list of running downloads from the remote repository.",
+        security = {
+            @SecurityRequirement(
+                name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
+            )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the artifact was deleted"
+            ),
+            @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+                content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+        }
+    )
+    List<String> getRunningRemoteDownloads();
+
+
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RestConfiguration.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RestConfiguration.java
new file mode 100644 (file)
index 0000000..10118d0
--- /dev/null
@@ -0,0 +1,43 @@
+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
+ * 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.
+ */
+
+/*
+ * 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.
+ */
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface RestConfiguration
+{
+    String DEFAULT_PAGE_LIMIT = "10";
+}
index 36dd46269e3fab61a62084a96ac417d0edbd8ac2..e8cc0d9cbc09fd53219b3b14d22e60eb295b28fe 100644 (file)
@@ -1,4 +1,5 @@
-package org.apache.archiva.rest.api.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
@@ -18,12 +19,10 @@ package org.apache.archiva.rest.api.services.v2;/*
 
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.Parameters;
 import io.swagger.v3.oas.annotations.enums.ParameterIn;
 import io.swagger.v3.oas.annotations.media.ArraySchema;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.parameters.RequestBody;
 import io.swagger.v3.oas.annotations.responses.ApiResponse;
 import io.swagger.v3.oas.annotations.security.SecurityRequirement;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -37,7 +36,6 @@ import org.apache.archiva.rest.api.model.v2.SecurityConfiguration;
 import org.apache.archiva.security.common.ArchivaRoleConstants;
 
 import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -46,12 +44,11 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.util.List;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static org.apache.archiva.rest.api.services.v2.Configuration.DEFAULT_PAGE_LIMIT;
+import static org.apache.archiva.rest.api.services.v2.RestConfiguration.DEFAULT_PAGE_LIMIT;
 
 /**
  *
index 6aec318dae204bf68ada9e0fc3b8dbdbfc0d692b..42a0a9279a951b6c1597aafb54574328a6ad88c8 100644 (file)
@@ -136,16 +136,17 @@ public class DefaultManagedRepositoriesService
 
 
     @Override
-    public ActionStatus updateManagedRepository( ManagedRepository managedRepository )
+    public Boolean updateManagedRepository( ManagedRepository managedRepository )
         throws ArchivaRestServiceException
     {
 
         try
         {
-            return new ActionStatus( managedRepositoryAdmin.updateManagedRepository( managedRepository,
+            managedRepositoryAdmin.updateManagedRepository( managedRepository,
                 managedRepository.isStageRepoNeeded( ),
                 getAuditInformation( ),
-                managedRepository.isResetStats( ) ) );
+                managedRepository.isResetStats( ) );
+            return true;
         }
         catch ( RepositoryAdminException e )
         {
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultMavenManagedRepositoryService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultMavenManagedRepositoryService.java
new file mode 100644 (file)
index 0000000..3c9c3a6
--- /dev/null
@@ -0,0 +1,126 @@
+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 org.apache.archiva.admin.model.RepositoryAdminException;
+import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
+import org.apache.archiva.components.rest.model.PagedResult;
+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.ErrorMessage;
+import org.apache.archiva.rest.api.services.v2.MavenManagedRepositoryService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import javax.ws.rs.core.Response;
+import java.util.List;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class DefaultMavenManagedRepositoryService implements MavenManagedRepositoryService
+{
+    private static final Logger log = LoggerFactory.getLogger( DefaultMavenManagedRepositoryService.class );
+    private static final QueryHelper<org.apache.archiva.admin.model.beans.ManagedRepository> QUERY_HELPER = new QueryHelper<>( new String[]{"id", "name"} );
+    static
+    {
+        QUERY_HELPER.addStringFilter( "id", org.apache.archiva.admin.model.beans.ManagedRepository::getId );
+        QUERY_HELPER.addStringFilter( "name", org.apache.archiva.admin.model.beans.ManagedRepository::getName );
+        QUERY_HELPER.addStringFilter( "location", org.apache.archiva.admin.model.beans.ManagedRepository::getName );
+        QUERY_HELPER.addBooleanFilter( "snapshot", org.apache.archiva.admin.model.beans.ManagedRepository::isSnapshots );
+        QUERY_HELPER.addBooleanFilter( "release", org.apache.archiva.admin.model.beans.ManagedRepository::isReleases );
+        QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.admin.model.beans.ManagedRepository::getId );
+        QUERY_HELPER.addNullsafeFieldComparator( "name", org.apache.archiva.admin.model.beans.ManagedRepository::getName );
+    }
+
+    @Inject
+    private ManagedRepositoryAdmin managedRepositoryAdmin;
+
+
+    @Override
+    public PagedResult<MavenManagedRepository> getManagedRepositories( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws ArchivaRestServiceException
+    {
+        try
+        {
+            List<org.apache.archiva.admin.model.beans.ManagedRepository> result = managedRepositoryAdmin.getManagedRepositories( );
+            int totalCount = Math.toIntExact( result.stream( ).count( ) );
+        }
+        catch (ArithmeticException e) {
+            log.error( "Invalid number of repositories detected." );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.INVALID_RESULT_SET_ERROR ) );
+        }
+        catch ( RepositoryAdminException e )
+        {
+            e.printStackTrace( );
+        }
+        return null;
+
+    }
+
+    @Override
+    public MavenManagedRepository getManagedRepository( String repositoryId ) throws ArchivaRestServiceException
+    {
+        return null;
+    }
+
+    @Override
+    public Response deleteManagedRepository( String repositoryId, boolean deleteContent ) throws ArchivaRestServiceException
+    {
+        return null;
+    }
+
+    @Override
+    public MavenManagedRepository addManagedRepository( MavenManagedRepository managedRepository ) throws ArchivaRestServiceException
+    {
+        return null;
+    }
+
+    @Override
+    public MavenManagedRepository updateManagedRepository( MavenManagedRepository managedRepository ) throws ArchivaRestServiceException
+    {
+        return null;
+    }
+
+    @Override
+    public FileInfo getFileStatus( String repositoryId, String fileLocation ) throws ArchivaRestServiceException
+    {
+        return null;
+    }
+
+    @Override
+    public Response removeProjectVersion( String repositoryId, String namespace, String projectId, String version ) throws org.apache.archiva.rest.api.services.ArchivaRestServiceException
+    {
+        return null;
+    }
+
+    @Override
+    public Response deleteProject( String repositoryId, String namespace, String projectId ) throws org.apache.archiva.rest.api.services.ArchivaRestServiceException
+    {
+        return null;
+    }
+
+    @Override
+    public Response deleteNamespace( String repositoryId, String namespace ) throws org.apache.archiva.rest.api.services.ArchivaRestServiceException
+    {
+        return null;
+    }
+
+}
index e348cdcab090ee3f3b40898e6fecff59b04be0f2..42b71930642c97868fd87c9e2b1fe12c0b947dae 100644 (file)
@@ -16,6 +16,24 @@ package org.apache.archiva.rest.services.v2;/*
  * under the License.
  */
 
+/*
+ * 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.AuditInformation;
 import org.apache.archiva.admin.model.EntityExistsException;
 import org.apache.archiva.admin.model.EntityNotFoundException;
@@ -62,14 +80,11 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
     @Context
     UriInfo uriInfo;
 
-    private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryGroupService.class );
-
-    private static final QueryHelper<org.apache.archiva.admin.model.beans.RepositoryGroup> QUERY_HELPER = new QueryHelper<>( new String[]{"id"} );
-
     @Inject
     private RepositoryGroupAdmin repositoryGroupAdmin;
 
-
+    private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryGroupService.class );
+    private static final QueryHelper<org.apache.archiva.admin.model.beans.RepositoryGroup> QUERY_HELPER = new QueryHelper<>( new String[]{"id"} );
     static
     {
         QUERY_HELPER.addStringFilter( "id", org.apache.archiva.admin.model.beans.RepositoryGroup::getId );
@@ -116,7 +131,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
     {
         if ( StringUtils.isEmpty( repositoryGroupId ) )
         {
-            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_EXIST, "" ), 404 );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
         }
         try
         {
@@ -125,7 +140,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
         }
         catch ( EntityNotFoundException e )
         {
-            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_EXIST, repositoryGroupId ), 404 );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, repositoryGroupId ), 404 );
         }
         catch ( RepositoryAdminException e )
         {
@@ -197,7 +212,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
     {
         if ( StringUtils.isEmpty( repositoryGroupId ) )
         {
-            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_EXIST, "" ), 404 );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
         }
         org.apache.archiva.admin.model.beans.RepositoryGroup updateGroup = toModel( repositoryGroup );
         try
@@ -232,7 +247,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
         }
         catch ( EntityNotFoundException e )
         {
-            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_EXIST, repositoryGroupId ), 404 );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, repositoryGroupId ), 404 );
         }
         catch ( RepositoryAdminException e )
         {
@@ -245,7 +260,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
     {
         if ( StringUtils.isEmpty( repositoryGroupId ) )
         {
-            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_EXIST, "" ), 404 );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
         }
         try
         {
@@ -258,7 +273,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
         }
         catch ( EntityNotFoundException e )
         {
-            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_EXIST, repositoryGroupId ), 404 );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, repositoryGroupId ), 404 );
         }
         catch ( RepositoryAdminException e )
         {
@@ -273,11 +288,11 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
     {
         if ( StringUtils.isEmpty( repositoryGroupId ) )
         {
-            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_EXIST, "" ), 404 );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
         }
         if ( StringUtils.isEmpty( repositoryId ) )
         {
-            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_EXIST, "" ), 404 );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
         }
         try
         {
@@ -311,11 +326,11 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
     {
         if ( StringUtils.isEmpty( repositoryGroupId ) )
         {
-            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_EXIST, "" ), 404 );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
         }
         if ( StringUtils.isEmpty( repositoryId ) )
         {
-            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_EXIST, "" ), 404 );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
         }
         try
         {
@@ -338,15 +353,15 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
         {
             if ( repositoryGroupId.equals( e.getParameters( )[0] ) )
             {
-                throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_EXIST, repositoryGroupId ), 404 );
+                throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, repositoryGroupId ), 404 );
             }
             else if ( repositoryId.equals( e.getParameters( )[0] ) )
             {
-                throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_EXIST, repositoryGroupId ), 404 );
+                throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryGroupId ), 404 );
             }
         }
         log.warn( "Entity not found but neither group nor repo set in exception" );
-        throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_EXIST, repositoryGroupId ), 404 );
+        throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, repositoryGroupId ), 404 );
     }
 
 
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryService.java
new file mode 100644 (file)
index 0000000..4f34cd1
--- /dev/null
@@ -0,0 +1,229 @@
+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 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;
+import org.apache.archiva.repository.scanner.RepositoryScanner;
+import org.apache.archiva.repository.scanner.RepositoryScannerException;
+import org.apache.archiva.rest.api.model.v2.Artifact;
+import org.apache.archiva.rest.api.model.v2.ArtifactTransferRequest;
+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.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;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Service("v2.repositoryService#rest")
+public class DefaultRepositoryService implements RepositoryService
+{
+
+    @Inject
+    RepositoryRegistry repositoryRegistry;
+
+    @Inject
+    RepositoryStatisticsManager repositoryStatisticsManager;
+
+    @Inject
+    @Named(value="taskQueueExecutor#indexing")
+    TaskQueueExecutor<ArtifactIndexingTask> indexingTaskExecutor;
+
+    @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 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.addNullsafeFieldComparator( "id", org.apache.archiva.repository.Repository::getId );
+        QUERY_HELPER.addNullsafeFieldComparator( "name", org.apache.archiva.repository.Repository::getName );
+    }
+
+    @Override
+    public PagedResult<Repository> getRepositories( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order,
+                                                    String localeString) throws ArchivaRestServiceException
+    {
+        final Locale locale = StringUtils.isNotEmpty( localeString ) ? Locale.forLanguageTag( localeString ) : Locale.getDefault( );
+        boolean isAscending = QUERY_HELPER.isAscending( order );
+        Predicate<org.apache.archiva.repository.Repository> filter = QUERY_HELPER.getQueryFilter( searchTerm );
+        Comparator<org.apache.archiva.repository.Repository> comparator = QUERY_HELPER.getComparator( orderBy, isAscending );
+        try
+        {
+            int totalCount = Math.toIntExact( repositoryRegistry.getRepositories( ).stream( ).filter( filter ).count( ) );
+            return new PagedResult<>( totalCount, offset, limit, repositoryRegistry.getRepositories( ).stream( )
+                .filter( filter ).skip( offset ).limit( limit ).sorted( comparator ).map( repo -> Repository.of( repo, locale ) )
+                .collect( Collectors.toList( ) ) );
+        }
+        catch ( ArithmeticException e )
+        {
+            log.error( "Invalid integer conversion for totalCount" );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.INVALID_RESULT_SET_ERROR ) );
+        }
+    }
+
+    @Override
+    public RepositoryStatistics getManagedRepositoryStatistics( String repositoryId ) throws ArchivaRestServiceException
+    {
+        if (repositoryRegistry.getManagedRepository( repositoryId )==null) {
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_MANAGED_NOT_FOUND, repositoryId ), 404 );
+        }
+        try
+        {
+            return RepositoryStatistics.of( repositoryStatisticsManager.getLastStatistics( repositoryId ) );
+        }
+        catch ( MetadataRepositoryException e )
+        {
+            log.error( "Metadata error: {} ", e.getMessage( ), e );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_METADATA_ERROR, e.getMessage( ) ) );
+        }
+    }
+
+    @Override
+    public Response scheduleRepositoryScan( String repositoryId, boolean fullScan ) throws ArchivaRestServiceException
+    {
+        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 ) );
+            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( ) ) );
+        }
+    }
+
+    @Override
+    public RepositoryStatistics scanRepositoryImmediately( String repositoryId ) throws ArchivaRestServiceException
+    {
+        long sinceWhen = RepositoryScanner.FRESH_SCAN;
+        try
+        {
+            return RepositoryStatistics.of( repoScanner.scan( repositoryRegistry.getManagedRepository( repositoryId ), sinceWhen ) );
+        }
+        catch ( RepositoryScannerException e )
+        {
+            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;
+        }
+        catch ( TaskQueueException e )
+        {
+            log.error( "Could not get task information: {}", e.getMessage( ), e );
+            throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.TASK_QUEUE_FAILED, e.getMessage( ) ) );
+        }
+    }
+
+    @Override
+    public Response removeScanningTaskFromQueue( String repositoryId ) throws ArchivaRestServiceException
+    {
+        return null;
+    }
+
+    @Override
+    public Response copyArtifact( ArtifactTransferRequest artifactTransferRequest ) throws ArchivaRestServiceException
+    {
+        return null;
+    }
+
+    @Override
+    public Response scheduleDownloadRemoteIndex( String repositoryId, boolean now, boolean fullDownload ) throws ArchivaRestServiceException
+    {
+        return null;
+    }
+
+    @Override
+    public Response deleteArtifact( Artifact artifact ) throws ArchivaRestServiceException
+    {
+        return null;
+    }
+
+    @Override
+    public List<String> getRunningRemoteDownloads( )
+    {
+        return null;
+    }
+}
index c4ab09ee24e19181cb4b958092ad2a51ef2c5747..990207486c4f900ca3274395275f6b09181a268e 100644 (file)
@@ -16,6 +16,24 @@ package org.apache.archiva.rest.services.v2;/*
  * under the License.
  */
 
+/*
+ * 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.RedbackRuntimeConfiguration;
 import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin;
index a77d0e2743302eeea9245e541084cb052c496005..5544ff315afd63564667707a9df15d936febd75d 100644 (file)
@@ -16,6 +16,24 @@ package org.apache.archiva.rest.services.v2;/*
  * under the License.
  */
 
+/*
+ * 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.rest.api.services.v2.ErrorMessage;
 
 import java.util.List;
@@ -46,11 +64,16 @@ public interface ErrorKeys
 
     String MISSING_DATA = "archiva.missing.data";
 
-    String REPOSITORY_GROUP_NOT_EXIST = REPOSITORY_GROUP_PREFIX+"notexist";
+    String REPOSITORY_GROUP_NOT_FOUND = REPOSITORY_GROUP_PREFIX+"notfound";
     String REPOSITORY_GROUP_ADD_FAILED = REPOSITORY_GROUP_PREFIX+"add.failed"  ;
     String REPOSITORY_GROUP_EXIST = REPOSITORY_GROUP_PREFIX+"exists";
 
     String REPOSITORY_GROUP_DELETE_FAILED = REPOSITORY_GROUP_PREFIX + "delete.failed";
-    String REPOSITORY_NOT_EXIST = REPOSITORY_PREFIX + "notexist";
+    String REPOSITORY_NOT_FOUND = REPOSITORY_PREFIX + "notfound";
+    String REPOSITORY_MANAGED_NOT_FOUND = REPOSITORY_PREFIX + ".managed.notfound";
+
+    String REPOSITORY_METADATA_ERROR = REPOSITORY_PREFIX + "metadata_error";
 
+    String TASK_QUEUE_FAILED = PREFIX + "task.queue_failed";
+    String REPOSITORY_SCAN_FAILED = REPOSITORY_PREFIX + "scan.failed";
 }
index 46d4d3fc2bc5e14d6748a1a810d7803755f4f6df..53b445abbe4a5855d26e4d821e58e8a28be718aa 100644 (file)
     <jaxrs:serviceBeans>
       <ref bean="v2.defaultSecurityConfigurationService" />
       <ref bean="v2.repositoryGroupService#rest" />
+      <ref bean="v2.repositoryService#rest"/>
     </jaxrs:serviceBeans>
 
     <jaxrs:features>
index 0c8885161d017ac4a79b2f564e7753e1483e0505..19cf8fe1da6153f33d4d583637b202cf4e578446 100644 (file)
@@ -20,8 +20,11 @@ package org.apache.archiva.metadata.repository.stats.model;
  */
 
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.TimeZone;
 import java.util.stream.Collectors;
@@ -394,6 +397,16 @@ public class DefaultRepositoryStatistics
         customValues.put(fieldName, count);
     }
 
+    @Override
+    public List<String> getAvailableCustomValues( )
+    {
+        if (customValues==null) {
+            return Collections.emptyList( );
+        } else {
+            return new ArrayList<>( customValues.keySet( ) );
+        }
+    }
+
     private void createCustomValueMap( )
     {
         customValues = new ZeroForNullHashMap<>();
index e5fa94a9b33a1ed53a31773be4acc09bd44ca826..df80d3738dc271571ff2357f141a1a5f5d1cfcfc 100644 (file)
@@ -22,6 +22,7 @@ package org.apache.archiva.metadata.repository.stats.model;
 import org.apache.archiva.metadata.model.MetadataFacet;
 
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -106,4 +107,10 @@ public interface RepositoryStatistics extends MetadataFacet
      */
     void setCustomValue(String fieldName, long count);
 
+    /**
+     * Returns the list of field names of custom values stored in this instance.
+     * @return the list of stored custom values
+     */
+    List<String> getAvailableCustomValues();
+
 }