From: Martin Stockhammer Date: Sat, 23 Jan 2021 18:33:10 +0000 (+0100) Subject: Adding REST v2 interfaces X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=7eef53d7c5145de75ecb6734169bacb53b02f5a0;p=archiva.git Adding REST v2 interfaces --- diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/RepositoryGroup.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/RepositoryGroup.java index 7e39a3d80..d4c0041b2 100644 --- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/RepositoryGroup.java +++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/RepositoryGroup.java @@ -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 diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/pom.xml b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/pom.xml index 67efa7acd..ac1b0623c 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/pom.xml +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/pom.xml @@ -60,6 +60,14 @@ org.apache.archiva archiva-repository-scanner + + org.apache.archiva + archiva-scheduler-repository-api + + + org.apache.archiva + archiva-scheduler-indexing + org.apache.archiva diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/SearchRequest.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/SearchRequest.java index e38706ca0..cc470d9dc 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/SearchRequest.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/SearchRequest.java @@ -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 index 000000000..c8fae1e41 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/Artifact.java @@ -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 + */ +@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 index 000000000..ce22bc4ae --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ArtifactTransferRequest.java @@ -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 + */ +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; + } +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/BeanInformation.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/BeanInformation.java index 936ace0a3..b795acddc 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/BeanInformation.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/BeanInformation.java @@ -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 index 000000000..e1f423d2b --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/FileInfo.java @@ -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 + */ +@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 index 000000000..e4d668486 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/IndexingTask.java @@ -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 + */ +@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( ); + } + +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/LdapConfiguration.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/LdapConfiguration.java index d6802c6f2..d6d481a15 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/LdapConfiguration.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/LdapConfiguration.java @@ -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 properties = new TreeMap<>(); + private Map properties = new TreeMap<>(); private boolean writable = false; private List availableContextFactories; @@ -206,8 +225,11 @@ public class LdapConfiguration implements Serializable public void setProperties( Map 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 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 index 000000000..6a045b438 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MavenManagedRepository.java @@ -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 + */ +@Schema(name="MavenManagedRepository",description = "A managed repository stores artifacts locally") +public class MavenManagedRepository extends Repository +{ + private static final long serialVersionUID = -6853748886201905029L; + + boolean blocksRedeployments; + List 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 getReleaseSchemes( ) + { + return releaseSchemes; + } + + public void setReleaseSchemes( List 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 index 000000000..3f05fb4ee --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MavenRemoteRepository.java @@ -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 + * @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 extraParameters = new TreeMap<>( ); + Map 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 getExtraParameters( ) + { + return extraParameters; + } + + public void setExtraParameters( Map 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 getRequestHeader( ) + { + return requestHeader; + } + + public void setRequestHeader( Map 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( ); + } +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MergeConfiguration.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MergeConfiguration.java index c5e60dad8..95a286b31 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MergeConfiguration.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MergeConfiguration.java @@ -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 index 000000000..ea4993d98 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/Repository.java @@ -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 + * @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( ); + } +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryGroup.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryGroup.java index d550f27c9..7eea24702 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryGroup.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryGroup.java @@ -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 repositories = new ArrayList<>( ); + private List repositories = new ArrayList<>( ); private String location; MergeConfiguration mergeConfiguration; @@ -77,8 +95,7 @@ public class RepositoryGroup implements Serializable public void setRepositories( List 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 index 000000000..1417a1986 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryStatistics.java @@ -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 + * @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 totalCountForType = new TreeMap<>( ); + private Map 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 getTotalCountForType( ) + { + return totalCountForType; + } + + public void setTotalCountForType( Map 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 getCustomValues( ) + { + return customValues; + } + + public void setCustomValues( Map 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 index 000000000..9800bbbf2 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanStatus.java @@ -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 + */ +@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 indexingQueue = new ArrayList<>( ); + private List scanQueue = new ArrayList<>( ); + + public ScanStatus( ) + { + } + + public void updateScanInfo( RepositoryTask runningRepositoryTask, List taskQueue) { + List 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 taskQueue) { + List 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 getIndexingQueue( ) + { + return indexingQueue; + } + + public void setIndexingQueue( List indexingQueue ) + { + this.indexingQueue = new ArrayList<>( indexingQueue ); + } + + @Schema(name="scan_queue", description = "List of scan tasks waiting for execution") + public List getScanQueue( ) + { + return scanQueue; + } + + public void setScanQueue( List 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 index 000000000..96aa96f2f --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/ScanTask.java @@ -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 + */ +@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( ); + } +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/SecurityConfiguration.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/SecurityConfiguration.java index 1204e66e2..efe02a4f3 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/SecurityConfiguration.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/SecurityConfiguration.java @@ -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 activeUserManagers = new ArrayList<>( ); - private final List activeRbacManagers = new ArrayList<>( ); - private final Map properties = new TreeMap<>( ); + private List activeUserManagers = new ArrayList<>( ); + private List activeRbacManagers = new ArrayList<>( ); + private Map properties = new TreeMap<>( ); private boolean userCacheEnabled=false; private boolean ldapActive=false; @@ -64,8 +82,7 @@ public class SecurityConfiguration implements Serializable public void setActiveUserManagers( List 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 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 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 index 000000000..879bb8b50 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/ArtifactCleanupInfo.java @@ -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 + */ +@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 index 000000000..ebc506bd2 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/IndexCreationInfo.java @@ -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 + */ +@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 index 000000000..c7dedc500 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/RemoteIndexInfo.java @@ -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 + */ +@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 index 000000000..1014d9faa --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/repository/StagingInfo.java @@ -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 + */ +@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; + } +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/ManagedRepositoriesService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/ManagedRepositoriesService.java index 208f24f09..9941e832e 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/ManagedRepositoriesService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/ManagedRepositoriesService.java @@ -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; /** diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/ArchivaRestServiceException.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/ArchivaRestServiceException.java index c2ac99059..3aabbe91f 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/ArchivaRestServiceException.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/ArchivaRestServiceException.java @@ -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 index e0b63577a..000000000 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/Configuration.java +++ /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 - */ -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 index 000000000..cf1b05701 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/MavenManagedRepositoryService.java @@ -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 + * @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 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 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; + +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryGroupService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryGroupService.java index 08ff59e14..8a5b6eaeb 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryGroupService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryGroupService.java @@ -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 index 000000000..8092ac72f --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryService.java @@ -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 + * @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 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 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 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 index 000000000..10118d048 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RestConfiguration.java @@ -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 + */ +public interface RestConfiguration +{ + 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/SecurityConfigurationService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/SecurityConfigurationService.java index 36dd46269..e8cc0d9cb 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/SecurityConfigurationService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/SecurityConfigurationService.java @@ -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; /** * diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultManagedRepositoriesService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultManagedRepositoriesService.java index 6aec318da..42a0a9279 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultManagedRepositoriesService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultManagedRepositoriesService.java @@ -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 index 000000000..3c9c3a654 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultMavenManagedRepositoryService.java @@ -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 + */ +public class DefaultMavenManagedRepositoryService implements MavenManagedRepositoryService +{ + private static final Logger log = LoggerFactory.getLogger( DefaultMavenManagedRepositoryService.class ); + private static final QueryHelper 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 getManagedRepositories( String searchTerm, Integer offset, Integer limit, List orderBy, String order ) throws ArchivaRestServiceException + { + try + { + List 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; + } + +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryGroupService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryGroupService.java index e348cdcab..42b719306 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryGroupService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryGroupService.java @@ -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 QUERY_HELPER = new QueryHelper<>( new String[]{"id"} ); - @Inject private RepositoryGroupAdmin repositoryGroupAdmin; - + private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryGroupService.class ); + private static final QueryHelper 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 index 000000000..4f34cd135 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryService.java @@ -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 + * @since 3.0 + */ +@Service("v2.repositoryService#rest") +public class DefaultRepositoryService implements RepositoryService +{ + + @Inject + RepositoryRegistry repositoryRegistry; + + @Inject + RepositoryStatisticsManager repositoryStatisticsManager; + + @Inject + @Named(value="taskQueueExecutor#indexing") + TaskQueueExecutor indexingTaskExecutor; + + @Inject + @Named(value="taskQueueExecutor#repository-scanning") + TaskQueueExecutor 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 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 getRepositories( String searchTerm, Integer offset, Integer limit, List 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 filter = QUERY_HELPER.getQueryFilter( searchTerm ); + Comparator 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 getRunningRemoteDownloads( ) + { + return null; + } +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultSecurityConfigurationService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultSecurityConfigurationService.java index c4ab09ee2..990207486 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultSecurityConfigurationService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultSecurityConfigurationService.java @@ -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; diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/ErrorKeys.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/ErrorKeys.java index a77d0e274..5544ff315 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/ErrorKeys.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/ErrorKeys.java @@ -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"; } diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/resources/META-INF/spring-context.xml b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/resources/META-INF/spring-context.xml index 46d4d3fc2..53b445abb 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/resources/META-INF/spring-context.xml +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/resources/META-INF/spring-context.xml @@ -118,6 +118,7 @@ + diff --git a/archiva-modules/metadata/metadata-statistics-api/src/main/java/org/apache/archiva/metadata/repository/stats/model/DefaultRepositoryStatistics.java b/archiva-modules/metadata/metadata-statistics-api/src/main/java/org/apache/archiva/metadata/repository/stats/model/DefaultRepositoryStatistics.java index 0c8885161..19cf8fe1d 100644 --- a/archiva-modules/metadata/metadata-statistics-api/src/main/java/org/apache/archiva/metadata/repository/stats/model/DefaultRepositoryStatistics.java +++ b/archiva-modules/metadata/metadata-statistics-api/src/main/java/org/apache/archiva/metadata/repository/stats/model/DefaultRepositoryStatistics.java @@ -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 getAvailableCustomValues( ) + { + if (customValues==null) { + return Collections.emptyList( ); + } else { + return new ArrayList<>( customValues.keySet( ) ); + } + } + private void createCustomValueMap( ) { customValues = new ZeroForNullHashMap<>(); diff --git a/archiva-modules/metadata/metadata-statistics-api/src/main/java/org/apache/archiva/metadata/repository/stats/model/RepositoryStatistics.java b/archiva-modules/metadata/metadata-statistics-api/src/main/java/org/apache/archiva/metadata/repository/stats/model/RepositoryStatistics.java index e5fa94a9b..df80d3738 100644 --- a/archiva-modules/metadata/metadata-statistics-api/src/main/java/org/apache/archiva/metadata/repository/stats/model/RepositoryStatistics.java +++ b/archiva-modules/metadata/metadata-statistics-api/src/main/java/org/apache/archiva/metadata/repository/stats/model/RepositoryStatistics.java @@ -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 getAvailableCustomValues(); + }