+++ /dev/null
-package org.apache.archiva.rest.api.model.v2;
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.io.Serializable;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Schema(name="Artifact", description = "Information about artifacts")
-public class Artifact implements Serializable
-{
- private static final long serialVersionUID = 7581578317346876555L;
- private String name;
-
- @Schema(name="name",description = "The name of the artifact")
- public String getName( )
- {
- return name;
- }
-
- public void setName( String name )
- {
- this.name = name;
- }
-}
+++ /dev/null
-package org.apache.archiva.rest.api.model.v2;
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.io.Serializable;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-public class ArtifactTransferRequest implements Serializable
-{
- private static final long serialVersionUID = -7377281345536573342L;
-
- private String path;
-
- @Schema(description = "The path to the artifact")
- public String getPath( )
- {
- return path;
- }
-
- public void setPath( String path )
- {
- this.path = path;
- }
-}
+++ /dev/null
-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 javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-import java.util.Objects;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@XmlRootElement(name="beanInformation")
-@Schema(name="BeanInformation",description = "Information about a bean instance.")
-public class BeanInformation implements Serializable
-{
- private static final long serialVersionUID = -432385743277355987L;
- private String id;
- private String displayName;
- private String descriptionKey;
- private String defaultDescription;
- private boolean readonly;
-
- public BeanInformation( )
- {
- }
-
- public BeanInformation( String id, String displayName, String descriptionKey, String defaultDescription, boolean readonly )
- {
- this.id = id;
- this.displayName = displayName;
- this.descriptionKey = descriptionKey;
- this.defaultDescription = defaultDescription;
- this.readonly = readonly;
- }
-
- @Schema(description = "The identifier")
- public String getId( )
- {
- return id;
- }
-
- public void setId( String id )
- {
- this.id = id;
- }
-
- @Schema(name="display_name", description = "The display name")
- public String getDisplayName( )
- {
- return displayName;
- }
-
- public void setDisplayName( String displayName )
- {
- this.displayName = displayName;
- }
-
- @Schema(name="description_key", description = "The translation key for the description")
- public String getDescriptionKey( )
- {
- return descriptionKey;
- }
-
- public void setDescriptionKey( String descriptionKey )
- {
- this.descriptionKey = descriptionKey;
- }
-
- @Schema(name="default_description", description = "The description translated in the default language")
- public String getDefaultDescription( )
- {
- return defaultDescription;
- }
-
- public void setDefaultDescription( String defaultDescription )
- {
- this.defaultDescription = defaultDescription;
- }
-
- @Schema(description = "True, if this bean cannot be removed")
- public boolean isReadonly( )
- {
- return readonly;
- }
-
- public void setReadonly( boolean readonly )
- {
- this.readonly = readonly;
- }
-
- @Override
- public boolean equals( Object o )
- {
- if ( this == o ) return true;
- if ( o == null || getClass( ) != o.getClass( ) ) return false;
- BeanInformation that = (BeanInformation) o;
- return readonly == that.readonly && id.equals( that.id ) && Objects.equals( displayName, that.displayName ) && Objects.equals( descriptionKey, that.descriptionKey ) && Objects.equals( defaultDescription, that.defaultDescription );
- }
-
- @Override
- public int hashCode( )
- {
- return Objects.hash( id, displayName, descriptionKey, defaultDescription, readonly );
- }
-
- @Override
- public String toString( )
- {
- return "BeanInformation{" +
- "id='" + id + '\'' +
- ", display_name='" + displayName + '\'' +
- ", description_key='" + descriptionKey + '\'' +
- ", default_description='" + defaultDescription + '\'' +
- ", readonly=" + readonly +
- '}';
- }
-}
+++ /dev/null
-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 javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-
-/**
- * @author Olivier Lamy
- * @author Martin Stockhammer
- * @since 3.0
- */
-@XmlRootElement( name = "cacheConfiguration" )
-@Schema(name="CacheConfiguration",description = "Cache configuration attributes")
-public class CacheConfiguration
- implements Serializable
-{
- private static final long serialVersionUID = 5479989049980673894L;
- /**
- * TimeToIdleSeconds.
- */
- private int timeToIdleSeconds = -1;
-
- /**
- * TimeToLiveSeconds.
- */
- private int timeToLiveSeconds = -1;
-
- /**
- * max elements in memory.
- */
- private int maxEntriesInMemory = -1;
-
- /**
- * max elements on disk.
- */
- private int maxEntriesOnDisk = -1;
-
- public CacheConfiguration()
- {
- // no op
- }
-
- public static CacheConfiguration of( org.apache.archiva.admin.model.beans.CacheConfiguration beanConfiguration ) {
- CacheConfiguration newConfig = new CacheConfiguration( );
- newConfig.setMaxEntriesInMemory( beanConfiguration.getMaxElementsInMemory() );
- newConfig.setMaxEntriesOnDisk( beanConfiguration.getMaxElementsOnDisk() );
- newConfig.setTimeToIdleSeconds( beanConfiguration.getTimeToIdleSeconds( ) );
- newConfig.setTimeToLiveSeconds( beanConfiguration.getTimeToLiveSeconds( ) );
- return newConfig;
- }
-
- @Schema(name="time_to_idle_seconds", description = "The maximum number of seconds an element can exist in the cache without being accessed. "+
- "The element expires at this limit and will no longer be returned from the cache.")
- public int getTimeToIdleSeconds()
- {
- return timeToIdleSeconds;
- }
-
- public void setTimeToIdleSeconds( int timeToIdleSeconds )
- {
- this.timeToIdleSeconds = timeToIdleSeconds;
- }
-
- @Schema(name="time_to_live_seconds", description = "The maximum number of seconds an element can exist in the cache regardless of use. "+
- "The element expires at this limit and will no longer be returned from the cache.")
- public int getTimeToLiveSeconds()
- {
- return timeToLiveSeconds;
- }
-
- public void setTimeToLiveSeconds( int timeToLiveSeconds )
- {
- this.timeToLiveSeconds = timeToLiveSeconds;
- }
-
- @Schema(name="max_entries_in_memory", description = "The maximum cache entries to keep in memory. If the limit is reached, older entries will be evicted, or persisted on disk.")
- public int getMaxEntriesInMemory()
- {
- return maxEntriesInMemory;
- }
-
- public void setMaxEntriesInMemory( int maxEntriesInMemory )
- {
- this.maxEntriesInMemory = maxEntriesInMemory;
- }
-
- @Schema(name="max_entries_on_disk", description = "The maximum cache entries to keep on disk. If the limit is reached, older entries will be evicted.")
- public int getMaxEntriesOnDisk()
- {
- return maxEntriesOnDisk;
- }
-
- public void setMaxEntriesOnDisk( int maxEntriesOnDisk )
- {
- this.maxEntriesOnDisk = maxEntriesOnDisk;
- }
-
- @Override
- public boolean equals( Object o )
- {
- if ( this == o ) return true;
- if ( o == null || getClass( ) != o.getClass( ) ) return false;
-
- CacheConfiguration that = (CacheConfiguration) o;
-
- if ( timeToIdleSeconds != that.timeToIdleSeconds ) return false;
- if ( timeToLiveSeconds != that.timeToLiveSeconds ) return false;
- if ( maxEntriesInMemory != that.maxEntriesInMemory ) return false;
- return maxEntriesOnDisk == that.maxEntriesOnDisk;
- }
-
- @Override
- public int hashCode( )
- {
- int result = timeToIdleSeconds;
- result = 31 * result + timeToLiveSeconds;
- result = 31 * result + maxEntriesInMemory;
- result = 31 * result + maxEntriesOnDisk;
- return result;
- }
-
- @Override
- public String toString()
- {
- final StringBuilder sb = new StringBuilder();
- sb.append( "CacheConfiguration" );
- sb.append( "{time_to_idle_seconds=" ).append( timeToIdleSeconds );
- sb.append( ", time_to_live_seconds=" ).append( timeToLiveSeconds );
- sb.append( ", max_elements_in_memory=" ).append( maxEntriesInMemory );
- sb.append( ", max_elements_on_disk=" ).append( maxEntriesOnDisk );
- sb.append( '}' );
- return sb.toString();
- }
-}
+++ /dev/null
-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.storage.StorageAsset;
-
-import java.io.Serializable;
-import java.time.OffsetDateTime;
-import java.time.ZoneOffset;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Schema(name="FileInfo",description = "Information about a file stored in the repository")
-public class FileInfo implements Serializable
-{
- private static final long serialVersionUID = 900497784542880195L;
- private OffsetDateTime modified;
- private String fileName;
- private String path;
-
- public FileInfo( )
- {
- }
-
- public static FileInfo of( StorageAsset asset ) {
- FileInfo fileInfo = new FileInfo( );
- fileInfo.setFileName( asset.getName() );
- fileInfo.setPath( asset.getPath() );
- fileInfo.setModified( asset.getModificationTime( ).atOffset( ZoneOffset.UTC ) );
- return fileInfo;
- }
-
- @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( );
- }
-}
+++ /dev/null
-package org.apache.archiva.rest.api.model.v2;
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
-import org.apache.archiva.scheduler.repository.model.RepositoryTask;
-
-import java.io.Serializable;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Schema(name="IndexingTask",description = "Information about indexing tasks")
-public class IndexingTask implements Serializable
-{
- private static final long serialVersionUID = -1947200162602613310L;
- private String repositoryId = "";
- private boolean fullRepository;
- private boolean updateOnly;
- private String resource = "";
- private boolean running = false;
- private long maxExecutionTimeMs = 0;
-
- public static IndexingTask of( org.apache.archiva.admin.model.beans.IndexingTask repositoryTask ) {
- IndexingTask indexingTask = new IndexingTask( );
- indexingTask.setFullRepository( repositoryTask.isFullScan());
- indexingTask.setUpdateOnly( repositoryTask.isUpdateOnly() );
- indexingTask.setResource( repositoryTask.getResource() );
- indexingTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTimeMs() );
- indexingTask.setRepositoryId( repositoryTask.getRepositoryId() );
- 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( );
- }
-
-}
+++ /dev/null
-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 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;
-import java.util.TreeMap;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-@XmlRootElement(name="ldapConfiguration")
-@Schema(name="LdapConfiguration", description = "LDAP configuration attributes")
-public class LdapConfiguration implements Serializable
-{
- private static final long serialVersionUID = -4736767846016398583L;
-
- private String hostName = "";
- private int port = 389;
- private String baseDn = "";
- private String groupsBaseDn = "";
- private String bindDn = "";
- private String bindPassword = "";
- private String authenticationMethod = "none";
- private String contextFactory;
- private boolean sslEnabled = false;
- private boolean bindAuthenticatorEnabled = true;
- private boolean useRoleNameAsGroup = false;
- private Map<String, String> properties = new TreeMap<>();
- private boolean writable = false;
- private List<String> availableContextFactories;
-
- public LdapConfiguration( )
- {
- }
-
- public static LdapConfiguration of( org.apache.archiva.admin.model.beans.LdapConfiguration ldapConfiguration ) {
- LdapConfiguration newCfg = new LdapConfiguration( );
- newCfg.setAuthenticationMethod( ldapConfiguration.getAuthenticationMethod( ) );
- newCfg.setBaseDn( ldapConfiguration.getBaseDn( ) );
- newCfg.setGroupsBaseDn( ldapConfiguration.getBaseGroupsDn() );
- newCfg.setBindDn( ldapConfiguration.getBindDn() );
- newCfg.setBindPassword( ldapConfiguration.getPassword() );
- newCfg.setBindAuthenticatorEnabled( ldapConfiguration.isBindAuthenticatorEnabled() );
- newCfg.setHostName( ldapConfiguration.getHostName( ) );
- newCfg.setSslEnabled( ldapConfiguration.isSsl() );
- newCfg.setContextFactory( ldapConfiguration.getContextFactory() );
- if (ldapConfiguration.getPort()<=0) {
- newCfg.setPort( newCfg.isSslEnabled() ? 636 : 389 );
- } else
- {
- newCfg.setPort( ldapConfiguration.getPort( ) );
- }
- newCfg.setProperties( ldapConfiguration.getExtraProperties( ) );
- newCfg.setWritable( ldapConfiguration.isWritable() );
- return newCfg;
- }
-
- @Schema(name="host_name", description = "The hostname to use to connect to the LDAP server")
- public String getHostName( )
- {
- return hostName;
- }
-
- public void setHostName( String hostName )
- {
- this.hostName = hostName==null?"":hostName;
- }
-
- @Schema(description = "The port to use to connect to the LDAP server")
- public int getPort( )
- {
- return port;
- }
-
- public void setPort( int port )
- {
- this.port = port;
- }
-
- @Schema(name="context_factory",description = "The class name of the LDAP context factory")
- public String getContextFactory( )
- {
- return contextFactory;
- }
-
- public void setContextFactory( String contextFactory )
- {
- this.contextFactory = contextFactory;
- }
-
-
- @Schema(name="ssl_enabled", description = "True, if SSL/TLS should be used for connecting the LDAP server")
- public boolean isSslEnabled( )
- {
- return sslEnabled;
- }
-
- public void setSslEnabled( boolean sslEnabled )
- {
- this.sslEnabled = sslEnabled;
- }
-
- @Schema(name="base_dn", description = "The BASE DN used for the LDAP server")
- public String getBaseDn( )
- {
- return baseDn;
- }
-
- public void setBaseDn( String baseDn )
- {
- this.baseDn = baseDn == null ? "" : baseDn;
- }
-
- @Schema(name="bind_dn", description = "The distinguished name of the bind user which is used to bind to the LDAP server")
- public String getBindDn( )
- {
- return bindDn;
- }
-
- public void setBindDn( String bindDn )
- {
- this.bindDn = bindDn == null ? "" : bindDn;
- }
-
- @Schema(name="bind_password", description = "The password used to bind to the ldap server")
- public String getBindPassword( )
- {
- return bindPassword;
- }
-
- public void setBindPassword( String bindPassword )
- {
- this.bindPassword = bindPassword==null?"":bindPassword;
- }
-
- @Schema(name="groups_base_dn", description = "The distinguished name of the base to use for searching group.")
- public String getGroupsBaseDn( )
- {
- return groupsBaseDn;
- }
-
- public void setGroupsBaseDn( String groupsBaseDn )
- {
- this.groupsBaseDn = groupsBaseDn==null?"":groupsBaseDn;
- }
-
- @Schema(name="authentication_method", description = "The authentication method used to bind to the LDAP server (PLAINTEXT, SASL, ...)")
- public String getAuthenticationMethod( )
- {
- return authenticationMethod;
- }
-
- public void setAuthenticationMethod( String authenticationMethod )
- {
- this.authenticationMethod = authenticationMethod==null?"":authenticationMethod;
- }
-
- @Schema(name="bind_authenticator_enabled", description = "True, if the LDAP bind authentication is used for logging in to Archiva")
- public boolean isBindAuthenticatorEnabled( )
- {
- return bindAuthenticatorEnabled;
- }
-
- public void setBindAuthenticatorEnabled( boolean bindAuthenticatorEnabled )
- {
- this.bindAuthenticatorEnabled = bindAuthenticatorEnabled;
- }
-
- @Schema(name="user_role_name_as_group", description = "True, if the archiva role name is also the LDAP group name")
- public boolean isUseRoleNameAsGroup( )
- {
- return useRoleNameAsGroup;
- }
-
- public void setUseRoleNameAsGroup( boolean useRoleNameAsGroup )
- {
- this.useRoleNameAsGroup = useRoleNameAsGroup;
- }
-
- @Schema(description = "LDAP ConnectionFactory environment properties")
- public Map<String, String> getProperties( )
- {
- return properties;
- }
-
- public void setProperties( Map<String, String> 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")
- public boolean isWritable( )
- {
- return writable;
- }
-
- public void setWritable( boolean writable )
- {
- this.writable = writable;
- }
-
- @Schema(name="available_context_factories", description = "The LDAP context factories that are known and available")
- public List<String> getAvailableContextFactories( )
- {
- return availableContextFactories;
- }
-
- public void setAvailableContextFactories( List<String> availableContextFactories )
- {
- this.availableContextFactories = new ArrayList<>( availableContextFactories );
- }
-
- public void addAvailableContextFactory(String contextFactory) {
- if (!this.availableContextFactories.contains( contextFactory ) ) {
- this.availableContextFactories.add( contextFactory );
- }
- }
-
-
-
- @Override
- public boolean equals( Object o )
- {
- if ( this == o ) return true;
- if ( o == null || getClass( ) != o.getClass( ) ) return false;
-
- LdapConfiguration that = (LdapConfiguration) o;
-
- if ( port != that.port ) return false;
- if ( sslEnabled != that.sslEnabled ) return false;
- if ( bindAuthenticatorEnabled != that.bindAuthenticatorEnabled ) return false;
- if ( useRoleNameAsGroup != that.useRoleNameAsGroup ) return false;
- if ( writable != that.writable ) return false;
- if ( !Objects.equals( hostName, that.hostName ) ) return false;
- if ( !Objects.equals( baseDn, that.baseDn ) ) return false;
- if ( !Objects.equals( bindDn, that.bindDn ) ) return false;
- if ( !Objects.equals( groupsBaseDn, that.groupsBaseDn ) )
- return false;
- if ( !Objects.equals( bindPassword, that.bindPassword ) ) return false;
- if ( !Objects.equals( authenticationMethod, that.authenticationMethod ) )
- return false;
- return properties.equals( that.properties );
- }
-
- @Override
- public int hashCode( )
- {
- int result = hostName != null ? hostName.hashCode( ) : 0;
- result = 31 * result + port;
- result = 31 * result + ( sslEnabled ? 1 : 0 );
- result = 31 * result + ( baseDn != null ? baseDn.hashCode( ) : 0 );
- result = 31 * result + ( bindDn != null ? bindDn.hashCode( ) : 0 );
- result = 31 * result + ( groupsBaseDn != null ? groupsBaseDn.hashCode( ) : 0 );
- result = 31 * result + ( bindPassword != null ? bindPassword.hashCode( ) : 0 );
- result = 31 * result + ( authenticationMethod != null ? authenticationMethod.hashCode( ) : 0 );
- result = 31 * result + ( bindAuthenticatorEnabled ? 1 : 0 );
- result = 31 * result + ( useRoleNameAsGroup ? 1 : 0 );
- result = 31 * result + properties.hashCode( );
- result = 31 * result + ( writable ? 1 : 0 );
- return result;
- }
-
- @SuppressWarnings( "StringBufferReplaceableByString" )
- @Override
- public String toString( )
- {
- final StringBuilder sb = new StringBuilder( "LdapConfiguration{" );
- sb.append( "host_name='" ).append( hostName ).append( '\'' );
- sb.append( ", port=" ).append( port );
- sb.append( ", ssl_enabled=" ).append( sslEnabled );
- sb.append( ", base_dn='" ).append( baseDn ).append( '\'' );
- sb.append( ", groups_base_dn='" ).append( groupsBaseDn ).append( '\'' );
- sb.append( ", bind_dn='" ).append( bindDn ).append( '\'' );
- sb.append( ", bind_password='" ).append( bindPassword ).append( '\'' );
- sb.append( ", authentication_method='" ).append( authenticationMethod ).append( '\'' );
- sb.append( ", bind_authenticator_enabled=" ).append( bindAuthenticatorEnabled );
- sb.append( ", use_role_name_as_group=" ).append( useRoleNameAsGroup );
- sb.append( ", properties=" ).append( properties );
- sb.append( ", writable=" ).append( writable );
- sb.append( '}' );
- return sb.toString( );
- }
-}
+++ /dev/null
-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.RepositoryType;
-import org.apache.archiva.repository.features.ArtifactCleanupFeature;
-import org.apache.archiva.repository.features.IndexCreationFeature;
-import org.apache.archiva.repository.features.StagingRepositoryFeature;
-
-import java.time.Period;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Schema(name="MavenManagedRepository",description = "A managed repository stores artifacts locally")
-public class MavenManagedRepository extends Repository
-{
- private static final long serialVersionUID = -6853748886201905029L;
-
- boolean blocksRedeployments;
- List<String> releaseSchemes = new ArrayList<>( );
- boolean deleteSnapshotsOfRelease = false;
- private Period retentionPeriod;
- private int retentionCount;
- private String indexPath;
- private String packedIndexPath;
- private boolean skipPackedIndexCreation;
- private boolean hasStagingRepository;
- private String stagingRepository;
-
-
- public MavenManagedRepository( )
- {
- super.setCharacteristic( Repository.CHARACTERISTIC_MANAGED );
- super.setType( RepositoryType.MAVEN.name( ) );
- }
-
- protected static void update(MavenManagedRepository repo, ManagedRepository beanRepo) {
- repo.setDescription( beanRepo.getDescription() );
- repo.setId( beanRepo.getId() );
- repo.setIndex( true );
- repo.setLayout( beanRepo.getLayout() );
- repo.setBlocksRedeployments( beanRepo.blocksRedeployments() );
- repo.setReleaseSchemes( beanRepo.getActiveReleaseSchemes().stream().map( Objects::toString).collect( Collectors.toList()) );
- repo.setLocation( beanRepo.getLocation().toString() );
- repo.setName( beanRepo.getName());
- repo.setScanned( beanRepo.isScanned() );
- repo.setSchedulingDefinition( beanRepo.getSchedulingDefinition() );
- ArtifactCleanupFeature artifactCleanupFeature = beanRepo.getFeature( ArtifactCleanupFeature.class ).get( );
- repo.setDeleteSnapshotsOfRelease( artifactCleanupFeature.isDeleteReleasedSnapshots());
- repo.setRetentionCount( artifactCleanupFeature.getRetentionCount());
- repo.setRetentionPeriod( artifactCleanupFeature.getRetentionPeriod() );
- IndexCreationFeature icf = beanRepo.getFeature( IndexCreationFeature.class ).get( );
- repo.setIndex( icf.hasIndex( ) );
- repo.setIndexPath( icf.getIndexPath( ).getPath( ) );
- repo.setPackedIndexPath( icf.getPackedIndexPath( ).getPath( ) );
- repo.setSkipPackedIndexCreation( icf.isSkipPackedIndexCreation() );
- StagingRepositoryFeature srf = beanRepo.getFeature( StagingRepositoryFeature.class ).get( );
- repo.setHasStagingRepository( srf.isStageRepoNeeded( ) );
- repo.setStagingRepository( srf.getStagingRepository()!=null?srf.getStagingRepository().getId():"" );
- }
-
- public static MavenManagedRepository of( ManagedRepository beanRepo ) {
- MavenManagedRepository repo = new MavenManagedRepository( );
- update( repo, beanRepo );
- return repo;
- }
-
- @Schema(name="blocks_redeployments",description = "True, if redeployments to this repository are not allowed")
- public boolean isBlocksRedeployments( )
- {
- return blocksRedeployments;
- }
-
- public void setBlocksRedeployments( boolean blocksRedeployments )
- {
- this.blocksRedeployments = blocksRedeployments;
- }
-
- @Schema(name="release_schemes", description = "The release schemes this repository is used for (e.g. RELEASE, SNAPSHOT)")
- public List<String> getReleaseSchemes( )
- {
- return releaseSchemes;
- }
-
- public void setReleaseSchemes( List<String> releaseSchemes )
- {
- this.releaseSchemes = new ArrayList<>( releaseSchemes );
- }
-
- public void addReleaseScheme(String scheme) {
- if (!this.releaseSchemes.contains( scheme ))
- {
- this.releaseSchemes.add( scheme );
- }
- }
-
- @Schema(name="delete_snaphots_of_release", description = "True, if snapshots are deleted, after a version is released")
- public boolean isDeleteSnapshotsOfRelease( )
- {
- return deleteSnapshotsOfRelease;
- }
-
- public void setDeleteSnapshotsOfRelease( boolean deleteSnapshotsOfRelease )
- {
- this.deleteSnapshotsOfRelease = deleteSnapshotsOfRelease;
- }
-
- @Schema(name="retention_period", description = "The period after which snapshots are deleted.")
- public Period getRetentionPeriod( )
- {
- return retentionPeriod;
- }
-
- public void setRetentionPeriod( Period retentionPeriod )
- {
- this.retentionPeriod = retentionPeriod;
- }
-
- @Schema(name="retention_count", description = "Number of snapshot artifacts to keep.")
- public int getRetentionCount( )
- {
- return retentionCount;
- }
-
- public void setRetentionCount( int retentionCount )
- {
- this.retentionCount = retentionCount;
- }
-
- @Schema( name = "index_path", description = "Path to the directory that contains the index, 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 directory that contains the packed index, relative to the repository base directory" )
- public String getPackedIndexPath( )
- {
- return packedIndexPath;
- }
-
- public void setPackedIndexPath( String packedIndexPath )
- {
- this.packedIndexPath = packedIndexPath;
- }
-
- @Schema(name="skip_packed_index_creation", description = "True, if packed index is not created during index update")
- public boolean isSkipPackedIndexCreation( )
- {
- return skipPackedIndexCreation;
- }
-
- public void setSkipPackedIndexCreation( boolean skipPackedIndexCreation )
- {
- this.skipPackedIndexCreation = skipPackedIndexCreation;
- }
-
- @Schema(name="has_staging_repository", description = "True, if this repository has a staging repository assigned")
- public boolean isHasStagingRepository( )
- {
- return hasStagingRepository;
- }
-
- public void setHasStagingRepository( boolean hasStagingRepository )
- {
- this.hasStagingRepository = hasStagingRepository;
- }
-
- @Schema(name="staging_repository", description = "The id of the assigned staging repository")
- public String getStagingRepository( )
- {
- return stagingRepository;
- }
-
- public void setStagingRepository( String stagingRepository )
- {
- this.stagingRepository = stagingRepository;
- }
-
- @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( );
- }
-}
+++ /dev/null
-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 org.apache.archiva.repository.ManagedRepository;
-
-import java.io.Serializable;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-public class MavenManagedRepositoryUpdate extends MavenManagedRepository implements Serializable
-{
- private static final long serialVersionUID = -9181643343284109862L;
- private boolean resetStats = false;
-
- public static MavenManagedRepositoryUpdate of( ManagedRepository repository ) {
- MavenManagedRepositoryUpdate repo = new MavenManagedRepositoryUpdate( );
- update( repo, repository );
- return repo;
- }
-
- public boolean isResetStats( )
- {
- return resetStats;
- }
-
- public void setResetStats( boolean resetStats )
- {
- this.resetStats = resetStats;
- }
-}
+++ /dev/null
-package org.apache.archiva.rest.api.model.v2;
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-@Schema(name="MavenRemoteRepository",description = "A remote repository definition is used to pull artifacts from other repositories")
-public class MavenRemoteRepository extends Repository
-{
- private static final long serialVersionUID = 5625043398766480265L;
- String loginUser;
- String loginPassword;
- String checkPath;
- Map<String,String> extraParameters = new TreeMap<>( );
- Map<String,String> requestHeader = new TreeMap<>( );
- long timeoutMs;
-
- @Schema(name="login_user",description = "Username for login to the remote repository")
- public String getLoginUser( )
- {
- return loginUser;
- }
-
- public void setLoginUser( String loginUser )
- {
- this.loginUser = loginUser;
- }
-
- @Schema(name="login_password",description = "Password for connecting to the remote repository")
- public String getLoginPassword( )
- {
- return loginPassword;
- }
-
- public void setLoginPassword( String loginPassword )
- {
- this.loginPassword = loginPassword;
- }
-
- @Schema(name="check_path",description = "Path relative to the repository URL that is used to check of availability of the remote repository.")
- public String getCheckPath( )
- {
- return checkPath;
- }
-
- public void setCheckPath( String checkPath )
- {
- this.checkPath = checkPath;
- }
-
- @Schema(name="extra_parameters", description = "Key-Value map with extra parameters sent to the remote repository")
- public Map<String, String> getExtraParameters( )
- {
- return extraParameters;
- }
-
- public void setExtraParameters( Map<String, String> extraParameters )
- {
- this.extraParameters = new TreeMap<>( extraParameters );
- }
-
- public void addExtraParameter(String key, String value) {
- this.extraParameters.put( key, value );
- }
-
- @Schema(name="request_header",description = "Key-Value map with request headers that are sent to the remote repository")
- public Map<String, String> getRequestHeader( )
- {
- return requestHeader;
- }
-
- public void setRequestHeader( Map<String, String> requestHeader )
- {
- this.requestHeader = new TreeMap<>( requestHeader );
- }
-
- public void addRequestHeader(String headerName, String headerValue) {
- this.requestHeader.put( headerName, headerValue );
- }
-
- @Schema(name="timeout_ms", description = "The time in milliseconds after that a request to the remote repository is aborted")
- public long getTimeoutMs( )
- {
- return timeoutMs;
- }
-
- public void setTimeoutMs( long timeoutMs )
- {
- this.timeoutMs = timeoutMs;
- }
-
- @Override
- public boolean equals( Object o )
- {
- if ( this == o ) return true;
- if ( o == null || getClass( ) != o.getClass( ) ) return false;
- if ( !super.equals( o ) ) return false;
-
- MavenRemoteRepository that = (MavenRemoteRepository) o;
-
- if ( timeoutMs != that.timeoutMs ) return false;
- if ( loginUser != null ? !loginUser.equals( that.loginUser ) : that.loginUser != null ) return false;
- if ( loginPassword != null ? !loginPassword.equals( that.loginPassword ) : that.loginPassword != null )
- return false;
- if ( checkPath != null ? !checkPath.equals( that.checkPath ) : that.checkPath != null ) return false;
- if ( extraParameters != null ? !extraParameters.equals( that.extraParameters ) : that.extraParameters != null )
- return false;
- return requestHeader != null ? requestHeader.equals( that.requestHeader ) : that.requestHeader == null;
- }
-
- @Override
- public int hashCode( )
- {
- int result = super.hashCode( );
- result = 31 * result + ( loginUser != null ? loginUser.hashCode( ) : 0 );
- result = 31 * result + ( loginPassword != null ? loginPassword.hashCode( ) : 0 );
- result = 31 * result + ( checkPath != null ? checkPath.hashCode( ) : 0 );
- result = 31 * result + ( extraParameters != null ? extraParameters.hashCode( ) : 0 );
- result = 31 * result + ( requestHeader != null ? requestHeader.hashCode( ) : 0 );
- result = 31 * result + (int) ( timeoutMs ^ ( timeoutMs >>> 32 ) );
- return result;
- }
-
- @Override
- public String toString( )
- {
- final StringBuilder sb = new StringBuilder( "RemoteRepository{" );
- sb.append( "loginUser='" ).append( loginUser ).append( '\'' );
- sb.append( ", loginPassword='" ).append( loginPassword ).append( '\'' );
- sb.append( ", checkPath='" ).append( checkPath ).append( '\'' );
- sb.append( ", extraParameters=" ).append( extraParameters );
- sb.append( ", requestHeader=" ).append( requestHeader );
- sb.append( ", timeOut=" ).append( timeoutMs );
- sb.append( ", id='" ).append( id ).append( '\'' );
- sb.append( ", name='" ).append( name ).append( '\'' );
- sb.append( ", description='" ).append( description ).append( '\'' );
- sb.append( ", type='" ).append( type ).append( '\'' );
- sb.append( ", location='" ).append( location ).append( '\'' );
- sb.append( ", scanned=" ).append( scanned );
- sb.append( ", schedulingDefinition='" ).append( schedulingDefinition ).append( '\'' );
- sb.append( ", index=" ).append( index );
- sb.append( ", layout='" ).append( layout ).append( '\'' );
- sb.append( '}' );
- return sb.toString( );
- }
-}
+++ /dev/null
-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 javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-import java.util.Objects;
-
-import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_INDEX_PATH;
-
-/**
- * Index merge configuration.
- *
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-@XmlRootElement(name="mergeConfiguration")
-@Schema(name="MergeConfiguration", description = "Configuration settings for index merge of remote repositories.")
-public class MergeConfiguration implements Serializable
-{
- private static final long serialVersionUID = -3629274059574459133L;
-
- private String mergedIndexPath = DEFAULT_INDEX_PATH;
- private int mergedIndexTtlMinutes = 30;
- private String indexMergeSchedule = "";
-
- @Schema(name="merged_index_path", description = "The path where the merged index is stored. The path is relative to the repository directory of the group.")
- public String getMergedIndexPath( )
- {
- return mergedIndexPath;
- }
-
- public void setMergedIndexPath( String mergedIndexPath )
- {
- this.mergedIndexPath = mergedIndexPath;
- }
-
- @Schema(name="merged_index_ttl_minutes", description = "The Time to Life of the merged index in minutes.")
- public int getMergedIndexTtlMinutes( )
- {
- return mergedIndexTtlMinutes;
- }
-
- public void setMergedIndexTtlMinutes( int mergedIndexTtlMinutes )
- {
- this.mergedIndexTtlMinutes = mergedIndexTtlMinutes;
- }
-
- @Schema(name="index_merge_schedule", description = "Cron expression that defines the times/intervals for index merging.")
- public String getIndexMergeSchedule( )
- {
- return indexMergeSchedule;
- }
-
- public void setIndexMergeSchedule( String indexMergeSchedule )
- {
- this.indexMergeSchedule = indexMergeSchedule;
- }
-
- @Override
- public boolean equals( Object o )
- {
- if ( this == o ) return true;
- if ( o == null || getClass( ) != o.getClass( ) ) return false;
-
- MergeConfiguration that = (MergeConfiguration) o;
-
- if ( mergedIndexTtlMinutes != that.mergedIndexTtlMinutes ) return false;
- if ( !Objects.equals( mergedIndexPath, that.mergedIndexPath ) )
- return false;
- return Objects.equals( indexMergeSchedule, that.indexMergeSchedule );
- }
-
- @Override
- public int hashCode( )
- {
- int result = mergedIndexPath != null ? mergedIndexPath.hashCode( ) : 0;
- result = 31 * result + mergedIndexTtlMinutes;
- result = 31 * result + ( indexMergeSchedule != null ? indexMergeSchedule.hashCode( ) : 0 );
- return result;
- }
-
- @SuppressWarnings( "StringBufferReplaceableByString" )
- @Override
- public String toString( )
- {
- final StringBuilder sb = new StringBuilder( "MergeConfiguration{" );
- sb.append( "mergedIndexPath='" ).append( mergedIndexPath ).append( '\'' );
- sb.append( ", mergedIndexTtlMinutes=" ).append( mergedIndexTtlMinutes );
- sb.append( ", indexMergeSchedule='" ).append( indexMergeSchedule ).append( '\'' );
- sb.append( '}' );
- return sb.toString( );
- }
-}
+++ /dev/null
-package org.apache.archiva.rest.api.model.v2;/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import org.apache.archiva.repository.ManagedRepository;
-import org.apache.archiva.repository.RemoteRepository;
-
-import java.io.Serializable;
-import java.util.Locale;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-@Schema(description = "Repository data")
-public class Repository implements Serializable
-{
- private static final long serialVersionUID = -4741025877287175182L;
-
- public static final String CHARACTERISTIC_MANAGED = "managed";
- public static final String CHARACTERISTIC_REMOTE = "remote";
- public static final String CHARACTERISTIC_UNKNOWN = "unknown";
-
- protected String id;
- protected String name;
- protected String description;
- protected String type;
- protected String characteristic;
- protected String location;
- protected boolean scanned;
- protected String schedulingDefinition;
- protected boolean index;
- protected String layout;
-
- public Repository( )
- {
- }
-
- public static Repository of( org.apache.archiva.repository.Repository repository ) {
- Repository newRepo = new Repository( );
- newRepo.setId( repository.getId() );
- newRepo.setName( repository.getName( ) );
- newRepo.setDescription( repository.getDescription( ) );
- newRepo.setLocation( repository.getLocation().toASCIIString() );
- newRepo.setIndex( repository.hasIndex() );
- newRepo.setLayout( repository.getLayout() );
- newRepo.setType( repository.getType().name() );
- newRepo.setScanned( repository.isScanned() );
- newRepo.setSchedulingDefinition( repository.getSchedulingDefinition() );
- if (repository instanceof RemoteRepository ) {
- newRepo.setCharacteristic( CHARACTERISTIC_REMOTE );
- } else if (repository instanceof ManagedRepository ) {
- newRepo.setCharacteristic( CHARACTERISTIC_MANAGED );
- } else {
- newRepo.setCharacteristic( CHARACTERISTIC_UNKNOWN );
- }
- return newRepo;
- }
-
- public static Repository of( org.apache.archiva.repository.Repository repository, Locale locale ) {
- Locale myLocale;
- if (locale==null) {
- myLocale = Locale.getDefault( );
- } else {
- myLocale = locale;
- }
- String repoName = repository.getName( myLocale );
- if (repoName==null) {
- repoName = repository.getName( );
- }
- String description = repository.getDescription( myLocale );
- if (description==null) {
- description = repository.getDescription( );
- }
- Repository newRepo = new Repository( );
- newRepo.setId( repository.getId() );
- newRepo.setName( repoName );
- newRepo.setDescription( description );
- 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( );
- }
-}
+++ /dev/null
-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.Repository;
-import org.apache.archiva.repository.features.IndexCreationFeature;
-import org.apache.archiva.repository.features.RepositoryFeature;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@XmlRootElement(name="repositoryGroup")
-@Schema(name="RepositoryGroup", description = "Information about a repository group, which combines multiple repositories as one virtual repository.")
-public class RepositoryGroup implements Serializable
-{
- private static final long serialVersionUID = -7319687481737616081L;
- private String id;
- private String name;
- private List<String> repositories = new ArrayList<>( );
- private String location;
- MergeConfiguration mergeConfiguration;
-
- public RepositoryGroup( )
- {
- }
-
- public RepositoryGroup(String id) {
- this.id = id;
- }
-
- public static RepositoryGroup of( org.apache.archiva.repository.RepositoryGroup modelObj ) {
- RepositoryGroup result = new RepositoryGroup( );
- MergeConfiguration mergeConfig = new MergeConfiguration( );
- result.setMergeConfiguration( mergeConfig );
- result.setId( modelObj.getId() );
- result.setName( modelObj.getName() );
- result.setLocation( modelObj.getLocation().toString() );
- result.setRepositories( modelObj.getRepositories().stream().map( Repository::getId ).collect( Collectors.toList()) );
- if (modelObj.supportsFeature( IndexCreationFeature.class )) {
- IndexCreationFeature icf = modelObj.getFeature( IndexCreationFeature.class ).get();
- mergeConfig.setMergedIndexPath( icf.getIndexPath( ).toString() );
- mergeConfig.setMergedIndexTtlMinutes( modelObj.getMergedIndexTTL( ) );
- mergeConfig.setIndexMergeSchedule( modelObj.getSchedulingDefinition() );
- }
- return result;
- }
-
- @Schema(description = "The unique id of the repository group.")
- public String getId( )
- {
- return id;
- }
-
- public void setId( String id )
- {
- this.id = id;
- }
-
- @Schema(description = "The list of ids of repositories which are member of the repository group.")
- public List<String> getRepositories( )
- {
- return repositories;
- }
-
- public void setRepositories( List<String> repositories )
- {
- this.repositories = new ArrayList<>( repositories );
- }
-
- public void addRepository(String repositoryId) {
- if (!this.repositories.contains( repositoryId )) {
- this.repositories.add( repositoryId );
- }
- }
-
- @Schema(name="merge_configuration",description = "The configuration for index merge.")
- public MergeConfiguration getMergeConfiguration( )
- {
- return mergeConfiguration;
- }
-
- public void setMergeConfiguration( MergeConfiguration mergeConfiguration )
- {
- this.mergeConfiguration = mergeConfiguration;
- }
-
- @Schema(description = "The storage location of the repository. The merged index is stored relative to this location.")
- public String getLocation( )
- {
- return location;
- }
-
- public void setLocation( String location )
- {
- this.location = location;
- }
-
- @Schema(description = "The name of the repository group")
- public String getName( )
- {
- return name;
- }
-
- public void setName( String name )
- {
- this.name = name;
- }
-
- @Override
- public boolean equals( Object o )
- {
- if ( this == o ) return true;
- if ( o == null || getClass( ) != o.getClass( ) ) return false;
-
- RepositoryGroup that = (RepositoryGroup) o;
-
- return id.equals( that.id );
- }
-
- @Override
- public int hashCode( )
- {
- return id.hashCode( );
- }
-
- @Override
- public String toString( )
- {
- final StringBuilder sb = new StringBuilder( "RepositoryGroup{" );
- sb.append( "id='" ).append( id ).append( '\'' );
- sb.append( ", name='" ).append( name ).append( '\'' );
- sb.append( ", repositories=" ).append( repositories );
- sb.append( ", location='" ).append( location ).append( '\'' );
- sb.append( ", mergeConfiguration=" ).append( mergeConfiguration );
- sb.append( '}' );
- return sb.toString( );
- }
-}
+++ /dev/null
-package org.apache.archiva.rest.api.model.v2;/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import org.apache.archiva.repository.scanner.RepositoryScanStatistics;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-import java.time.Duration;
-import java.time.OffsetDateTime;
-import java.time.ZoneOffset;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-@XmlRootElement(name="repositoryStatistics")
-@Schema(name="RepositoryStatistics", description = "Statistics data")
-public class RepositoryStatistics implements Serializable
-{
- private static final long serialVersionUID = 7943367882738452531L;
-
- private OffsetDateTime scanEndTime;
- private OffsetDateTime scanStartTime;
- private long scanDurationMs;
- private long totalArtifactCount;
- private long totalArtifactFileSize;
- private long totalFileCount;
- private long totalGroupCount;
- private long totalProjectCount;
- private long newFileCount;
- private Map<String, Long> totalCountForType = new TreeMap<>( );
- private Map<String, Long> customValues = new TreeMap<>( );
-
- public RepositoryStatistics( )
- {
- }
-
- public static RepositoryStatistics of( org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics modelStats ) {
- RepositoryStatistics newStats = new RepositoryStatistics( );
- newStats.setScanStartTime( modelStats.getScanStartTime().toInstant().atOffset( ZoneOffset.UTC ) );
- newStats.setScanEndTime( modelStats.getScanEndTime( ).toInstant( ).atOffset( ZoneOffset.UTC ) );
- newStats.setNewFileCount( modelStats.getNewFileCount() );
- newStats.setScanDurationMs( Duration.between( newStats.scanStartTime, newStats.scanEndTime ).toMillis() );
- newStats.setTotalArtifactCount( modelStats.getTotalArtifactCount() );
- newStats.setTotalArtifactFileSize( modelStats.getTotalArtifactFileSize() );
- newStats.setTotalCountForType( modelStats.getTotalCountForType() );
- newStats.setTotalFileCount( modelStats.getTotalFileCount() );
- newStats.setTotalGroupCount( modelStats.getTotalGroupCount() );
- newStats.setTotalProjectCount( modelStats.getTotalProjectCount() );
- for (String key : modelStats.getAvailableCustomValues()) {
- newStats.addCustomValue( key, modelStats.getCustomValue( key ) );
- }
- return newStats;
- }
-
- public static RepositoryStatistics of( RepositoryScanStatistics scanStatistics ) {
- RepositoryStatistics newStats = new RepositoryStatistics( );
- newStats.setScanStartTime( scanStatistics.getWhenGathered().toInstant().atOffset( ZoneOffset.UTC ) );
- newStats.setScanEndTime( OffsetDateTime.now(ZoneOffset.UTC) );
- newStats.setNewFileCount( scanStatistics.getNewFileCount() );
- newStats.setScanDurationMs( Duration.between( newStats.scanStartTime, newStats.scanEndTime ).toMillis() );
- newStats.setTotalArtifactCount( scanStatistics.getTotalFileCount() );
- newStats.setTotalArtifactFileSize( scanStatistics.getTotalSize() );
- newStats.setTotalFileCount( scanStatistics.getTotalFileCount() );
- newStats.setTotalGroupCount( 0 );
- newStats.setTotalProjectCount( 0 );
- return newStats;
- }
-
- @Schema(name="scan_end_time", description = "Date and time when the last scan finished")
- public OffsetDateTime getScanEndTime( )
- {
- return scanEndTime;
- }
-
- public void setScanEndTime( OffsetDateTime scanEndTime )
- {
- this.scanEndTime = scanEndTime;
- }
-
- @Schema( name = "scan_start_time", description = "Date and time when the last scan started" )
- public OffsetDateTime getScanStartTime( )
- {
- return scanStartTime;
- }
-
- public void setScanStartTime( OffsetDateTime scanStartTime )
- {
- this.scanStartTime = scanStartTime;
- }
-
- @Schema(name="total_artifact_count", description = "The number of artifacts scanned")
- public long getTotalArtifactCount( )
- {
- return totalArtifactCount;
- }
-
- public void setTotalArtifactCount( long totalArtifactCount )
- {
- this.totalArtifactCount = totalArtifactCount;
- }
-
- @Schema(name="total_artifact_file_size", description = "The cumulative size of all files scanned")
- public long getTotalArtifactFileSize( )
- {
- return totalArtifactFileSize;
- }
-
- public void setTotalArtifactFileSize( long totalArtifactFileSize )
- {
- this.totalArtifactFileSize = totalArtifactFileSize;
- }
-
- @Schema(name="total_file_count", description = "The total number of files scanned")
- public long getTotalFileCount( )
- {
- return totalFileCount;
- }
-
- public void setTotalFileCount( long totalFileCount )
- {
- this.totalFileCount = totalFileCount;
- }
-
- @Schema(name="total_group_count", description = "The number of groups scanned")
- public long getTotalGroupCount( )
- {
- return totalGroupCount;
- }
-
- public void setTotalGroupCount( long totalGroupCount )
- {
- this.totalGroupCount = totalGroupCount;
- }
-
- @Schema(name="total_project_count", description = "The number of projects scanned")
- public long getTotalProjectCount( )
- {
- return totalProjectCount;
- }
-
- public void setTotalProjectCount( long totalProjectCount )
- {
- this.totalProjectCount = totalProjectCount;
- }
-
- @Schema(name="new_file_count", description = "Number of files registered as new")
- public long getNewFileCount( )
- {
- return newFileCount;
- }
-
- public void setNewFileCount( long newFileCount )
- {
- this.newFileCount = newFileCount;
- }
-
- @Schema(name="scan_duration_ms", description = "The duration of the last scan in ms")
- public long getScanDurationMs( )
- {
- return scanDurationMs;
- }
-
- public void setScanDurationMs( long scanDurationMs )
- {
- this.scanDurationMs = scanDurationMs;
- }
-
- @Schema(name="total_count_for_type", description = "File counts partitioned by file types")
- public Map<String, Long> getTotalCountForType( )
- {
- return totalCountForType;
- }
-
- public void setTotalCountForType( Map<String, Long> totalCountForType )
- {
- this.totalCountForType = new TreeMap<>( totalCountForType );
- }
-
- public void addTotalCountForType( String type, Long value )
- {
- this.totalCountForType.put( type, value );
- }
-
- @Schema(name="custom_values", description = "Custom statistic values")
- public Map<String, Long> getCustomValues( )
- {
- return customValues;
- }
-
- public void setCustomValues( Map<String, Long> customValues )
- {
- this.customValues = new TreeMap<>( customValues );
- }
-
- public void addCustomValue(String type, Long value) {
- this.customValues.put( type, value );
- }
-
- @Override
- public boolean equals( Object o )
- {
- if ( this == o ) return true;
- if ( o == null || getClass( ) != o.getClass( ) ) return false;
-
- RepositoryStatistics that = (RepositoryStatistics) o;
-
- if ( scanDurationMs != that.scanDurationMs ) return false;
- if ( totalArtifactCount != that.totalArtifactCount ) return false;
- if ( totalArtifactFileSize != that.totalArtifactFileSize ) return false;
- if ( totalFileCount != that.totalFileCount ) return false;
- if ( totalGroupCount != that.totalGroupCount ) return false;
- if ( totalProjectCount != that.totalProjectCount ) return false;
- if ( newFileCount != that.newFileCount ) return false;
- if ( scanEndTime != null ? !scanEndTime.equals( that.scanEndTime ) : that.scanEndTime != null ) return false;
- if ( scanStartTime != null ? !scanStartTime.equals( that.scanStartTime ) : that.scanStartTime != null )
- return false;
- if ( !totalCountForType.equals( that.totalCountForType ) ) return false;
- return customValues.equals( that.customValues );
- }
-
- @Override
- public int hashCode( )
- {
- int result = scanEndTime != null ? scanEndTime.hashCode( ) : 0;
- result = 31 * result + ( scanStartTime != null ? scanStartTime.hashCode( ) : 0 );
- result = 31 * result + (int) ( scanDurationMs ^ ( scanDurationMs >>> 32 ) );
- result = 31 * result + (int) ( totalArtifactCount ^ ( totalArtifactCount >>> 32 ) );
- result = 31 * result + (int) ( totalArtifactFileSize ^ ( totalArtifactFileSize >>> 32 ) );
- result = 31 * result + (int) ( totalFileCount ^ ( totalFileCount >>> 32 ) );
- result = 31 * result + (int) ( totalGroupCount ^ ( totalGroupCount >>> 32 ) );
- result = 31 * result + (int) ( totalProjectCount ^ ( totalProjectCount >>> 32 ) );
- result = 31 * result + (int) ( newFileCount ^ ( newFileCount >>> 32 ) );
- result = 31 * result + totalCountForType.hashCode( );
- result = 31 * result + customValues.hashCode( );
- return result;
- }
-
- @Override
- public String toString( )
- {
- final StringBuilder sb = new StringBuilder( "RepositoryStatistics{" );
- sb.append( "scanEndTime=" ).append( scanEndTime );
- sb.append( ", scanStartTime=" ).append( scanStartTime );
- sb.append( ", scanDurationMs=" ).append( scanDurationMs );
- sb.append( ", totalArtifactCount=" ).append( totalArtifactCount );
- sb.append( ", totalArtifactFileSize=" ).append( totalArtifactFileSize );
- sb.append( ", totalFileCount=" ).append( totalFileCount );
- sb.append( ", totalGroupCount=" ).append( totalGroupCount );
- sb.append( ", totalProjectCount=" ).append( totalProjectCount );
- sb.append( ", newFileCount=" ).append( newFileCount );
- sb.append( '}' );
- return sb.toString( );
- }
-}
+++ /dev/null
-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.admin.model.beans.MetadataScanTask;
-import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
-import org.apache.archiva.scheduler.repository.model.RepositoryTask;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Schema(name="ScanStatus", description = "Status of repository scan tasks")
-public class ScanStatus implements Serializable
-{
- private boolean scanRunning = false;
- private int scanQueued = 0;
- private boolean indexRunning = false;
- private int indexQueued = 0;
- private List<IndexingTask> indexingQueue = new ArrayList<>( );
- private List<ScanTask> scanQueue = new ArrayList<>( );
-
- public ScanStatus( )
- {
- }
-
- public static ScanStatus of( org.apache.archiva.admin.model.beans.ScanStatus modelStatus ) {
- ScanStatus status = new ScanStatus( );
- status.setIndexRunning( modelStatus.isIndexScanRunning() );
- status.setScanRunning( modelStatus.isMetadataScanRunning() );
- List<org.apache.archiva.admin.model.beans.IndexingTask> indexQueue = modelStatus.getIndexingQueue( );
- status.setIndexingQueue( indexQueue.stream().map(IndexingTask::of).collect( Collectors.toList()) );
- status.setIndexQueued( indexQueue.size( ) > 0 ? indexQueue.size( ) - 1 : 0 );
- List<MetadataScanTask> scanQueue = modelStatus.getScanQueue( );
- status.setScanQueue( scanQueue.stream().map( ScanTask::of ).collect( Collectors.toList()) );
- status.setScanQueued( scanQueue.size( ) > 0 ? scanQueue.size( ) - 1 : 0 );
- return status;
-
- }
-
- @Schema( name = "scan_running", description = "True, if a scan is currently running" )
- public boolean isScanRunning( )
- {
- return scanRunning;
- }
-
- public void setScanRunning( boolean scanRunning )
- {
- this.scanRunning = scanRunning;
- }
-
- @Schema(name ="scan_queued", description = "Number of scans in the task queue")
- public int getScanQueued( )
- {
- return scanQueued;
- }
-
- public void setScanQueued( int scanQueued )
- {
- this.scanQueued = scanQueued;
- }
-
- @Schema(name="index_running", description = "True, if there is a index task currently running")
- public boolean isIndexRunning( )
- {
- return indexRunning;
- }
-
- public void setIndexRunning( boolean indexRunning )
- {
- this.indexRunning = indexRunning;
- }
-
- @Schema(name="index_queued", description = "Number of queued index tasks")
- public int getIndexQueued( )
- {
- return indexQueued;
- }
-
- public void setIndexQueued( int indexQueued )
- {
- this.indexQueued = indexQueued;
- }
-
- @Schema( name = "indexing_queue", description = "List of indexing tasks waiting for execution" )
- public List<IndexingTask> getIndexingQueue( )
- {
- return indexingQueue;
- }
-
- public void setIndexingQueue( List<IndexingTask> indexingQueue )
- {
- this.indexingQueue = new ArrayList<>( indexingQueue );
- }
-
- @Schema(name="scan_queue", description = "List of scan tasks waiting for execution")
- public List<ScanTask> getScanQueue( )
- {
- return scanQueue;
- }
-
- public void setScanQueue( List<ScanTask> scanQueue )
- {
- this.scanQueue = new ArrayList<>( scanQueue );
- }
-}
+++ /dev/null
-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.admin.model.beans.MetadataScanTask;
-import org.apache.archiva.scheduler.repository.model.RepositoryTask;
-
-import java.io.Serializable;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Schema(name="ScanTask", description = "Repository scan task information")
-public class ScanTask implements Serializable
-{
- private static final long serialVersionUID = -681163357370848098L;
- private String repositoryId="";
- private boolean updateRelatedArtifacts;
- private boolean fullRepository;
- private boolean running = false;
- private String resource = "";
- private long maxExecutionTimeMs = 0;
-
- public static ScanTask of( MetadataScanTask repositoryTask ) {
- ScanTask scanTask = new ScanTask( );
- scanTask.setFullRepository( repositoryTask.isFullScan());
- scanTask.setUpdateRelatedArtifacts( repositoryTask.isUpdateRelatedArtifacts() );
- scanTask.setResource( repositoryTask.getResource() );
- scanTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTimeMs() );
- 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( );
- }
-}
+++ /dev/null
-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.admin.model.beans.RedbackRuntimeConfiguration;
-
-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.TreeMap;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@XmlRootElement(name = "securityConfiguration")
-@Schema(name = "SecurityConfiguration", description = "Security configuration attributes.")
-public class SecurityConfiguration implements Serializable
-{
- private static final long serialVersionUID = -4186866365979053029L;
-
- private List<String> activeUserManagers = new ArrayList<>( );
- private List<String> activeRbacManagers = new ArrayList<>( );
- private Map<String,String> properties = new TreeMap<>( );
- private boolean userCacheEnabled=false;
- private boolean ldapActive=false;
-
- public SecurityConfiguration() {
-
- }
-
- public static SecurityConfiguration ofRedbackConfiguration( RedbackRuntimeConfiguration configuration ) {
- SecurityConfiguration secConfig = new SecurityConfiguration( );
- secConfig.setActiveRbacManagers( configuration.getRbacManagerImpls() );
- secConfig.setActiveUserManagers( configuration.getUserManagerImpls() );
- secConfig.setProperties( configuration.getConfigurationProperties() );
- boolean rbLdapActive = configuration.getUserManagerImpls( ).stream( ).anyMatch( um -> um.contains( "ldap" ) );
- secConfig.setLdapActive( rbLdapActive );
- secConfig.setUserCacheEnabled( configuration.isUseUsersCache() );
- return secConfig;
- }
-
- @Schema(name="active_user_managers", description = "List of ids of the active user managers")
- public List<String> getActiveUserManagers( )
- {
- return activeUserManagers;
- }
-
- public void setActiveUserManagers( List<String> activeUserManagers )
- {
- this.activeUserManagers = new ArrayList<>( activeUserManagers );
- }
-
- public void addSelectedUserManager(String userManager) {
- this.activeUserManagers.add( userManager );
- }
-
- @Schema(name="active_rbac_managers", description = "List of ids of the active rbac managers")
- public List<String> getActiveRbacManagers( )
- {
- return activeRbacManagers;
- }
-
- public void setActiveRbacManagers( List<String> activeRbacManagers )
- {
- this.activeRbacManagers = new ArrayList<>( activeRbacManagers );
- }
-
- public void addSelectedRbacManager(String rbacManager) {
- this.activeRbacManagers.add( rbacManager );
- }
-
- @Schema(description = "Map of all security properties")
- public Map<String, String> getProperties( )
- {
- return properties;
- }
-
- public void setProperties( Map<String, String> 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.")
- public boolean isUserCacheEnabled( )
- {
- return userCacheEnabled;
- }
-
- public void setUserCacheEnabled( boolean userCacheEnabled )
- {
- this.userCacheEnabled = userCacheEnabled;
- }
-
- @Schema(name="ldap_active", description = "True, if LDAP is used as user manager")
- public boolean isLdapActive( )
- {
- return ldapActive;
- }
-
- public void setLdapActive( boolean ldapActive )
- {
- this.ldapActive = ldapActive;
- }
-
- @Override
- public boolean equals( Object o )
- {
- if ( this == o ) return true;
- if ( o == null || getClass( ) != o.getClass( ) ) return false;
-
- SecurityConfiguration that = (SecurityConfiguration) o;
-
- if ( userCacheEnabled != that.userCacheEnabled ) return false;
- if ( ldapActive != that.ldapActive ) return false;
- if ( !activeUserManagers.equals( that.activeUserManagers ) ) return false;
- if ( !activeRbacManagers.equals( that.activeRbacManagers ) ) return false;
- return properties.equals( that.properties );
- }
-
- @Override
- public int hashCode( )
- {
- int result = activeUserManagers.hashCode( );
- result = 31 * result + activeRbacManagers.hashCode( );
- result = 31 * result + properties.hashCode( );
- result = 31 * result + ( userCacheEnabled ? 1 : 0 );
- result = 31 * result + ( ldapActive ? 1 : 0 );
- return result;
- }
-
- @SuppressWarnings( "StringBufferReplaceableByString" )
- @Override
- public String toString( )
- {
- final StringBuilder sb = new StringBuilder( "SecurityConfiguration{" );
- sb.append( "active_user_managers=" ).append( activeUserManagers );
- sb.append( ", active_rbac_managers=" ).append( activeRbacManagers );
- sb.append( ", properties=" ).append( properties );
- sb.append( ", user_cache_enabled=" ).append( userCacheEnabled );
- sb.append( ", ldap_active=" ).append( ldapActive );
- sb.append( '}' );
- return sb.toString( );
- }
-}
+++ /dev/null
-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 javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@XmlRootElement(name = "validationError")
-@Schema(name = "ValidationError", description = "A validation error.")
-public class ValidationError implements Serializable
-{
- private static final long serialVersionUID = 2079020598090660171L;
-
- String key;
- String field;
- String category;
- String type;
- List<String> parameter;
-
-
- public ValidationError( )
- {
- }
-
- public ValidationError( String key, String field, String category, String type, List<String> parameter) {
- this.key = key;
- this.field = field;
- this.category = category;
- this.type = type;
- if (parameter==null) {
- this.parameter = new ArrayList<>( );
- } else
- {
- this.parameter = parameter;
- }
- }
-
- /**
- * Creates a new instance based on the given error
- * @param error the error instance
- * @return
- */
- public static ValidationError of( org.apache.archiva.repository.validation.ValidationError error ) {
- return error != null ? new ValidationError( error.getErrorKey( ), error.getAttribute( ), error.getCategory( ),
- error.getType( ), error.getArguments( ).stream( ).map( Object::toString ).collect( Collectors.toList( ) ) )
- : new ValidationError( );
- }
-
- /**
- * Creates a new instance based on the field name and the error instance
- * @param fieldName the name of the field to which the error applies
- * @param error the error definition
- * @return a new validation error instance
- */
- public static ValidationError of( String fieldName, org.apache.archiva.repository.validation.ValidationError error ) {
- return error != null ? new ValidationError( error.getErrorKey( ), fieldName, error.getCategory( ),
- error.getType( ), error.getArguments( ).stream( ).map( Object::toString ).collect( Collectors.toList( ) ) )
- : new ValidationError( );
- }
-
- @Schema(name="key", description = "The full key of the validation error")
- public String getKey( )
- {
- return key;
- }
-
- public void setKey( String key )
- {
- this.key = key;
- }
-
- @Schema(name="field", description = "The name of the field where the error was detected")
- public String getField( )
- {
- return field;
- }
-
- public void setField( String field )
- {
- this.field = field;
- }
-
- @Schema(name="category", description = "The name of the category this error is assigned to")
- public String getCategory( )
- {
- return category;
- }
-
- public void setCategory( String category )
- {
- this.category = category;
- }
-
- @Schema(name="type", description = "The type of the error. This is a unique string that defines the type of error, e.g. empty, bad_number_range, ... .")
- public String getType( )
- {
- return type;
- }
-
- public void setType( String type )
- {
- this.type = type;
- }
-
- @Schema(name="parameter", description = "The list of parameters, that can be used to create a translated error message")
- public List<String> getParameter( )
- {
- return parameter;
- }
-
- public void setParameter( List<String> parameter )
- {
- this.parameter = parameter;
- }
-}
+++ /dev/null
-package org.apache.archiva.rest.api.model.v2.repository;/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.time.Period;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Schema(name="ArtifactCleanupInfo",description = "Information for artifact cleanup feature of repository")
-public class ArtifactCleanupInfo
-{
- boolean deleteReleasedSnapshots;
- Period retentionPeriod;
- int retentionCount;
-
- @Schema(name="delete_released_snapshots",description = "True, if snapshots are deleted after a release was published")
- public boolean isDeleteReleasedSnapshots( )
- {
- return deleteReleasedSnapshots;
- }
-
- public void setDeleteReleasedSnapshots( boolean deleteReleasedSnapshots )
- {
- this.deleteReleasedSnapshots = deleteReleasedSnapshots;
- }
-
- @Schema(name="retention_period",description = "Time, after that snapshot artifacts are marked for deletion")
- public Period getRetentionPeriod( )
- {
- return retentionPeriod;
- }
-
- public void setRetentionPeriod( Period retentionPeriod )
- {
- this.retentionPeriod = retentionPeriod;
- }
-
- @Schema(name="retention_count",description = "Maximum number of snapshot artifacts to keep")
- public int getRetentionCount( )
- {
- return retentionCount;
- }
-
- public void setRetentionCount( int retentionCount )
- {
- this.retentionCount = retentionCount;
- }
-}
+++ /dev/null
-package org.apache.archiva.rest.api.model.v2.repository;/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import org.apache.archiva.repository.Repository;
-import org.apache.archiva.repository.storage.StorageAsset;
-
-import java.net.URI;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Schema(name="IndexCreationInfo",description = "Information about index creation feature of repositories")
-public class IndexCreationInfo
-{
- private boolean skipPackedIndexCreation = false;
- private String indexPath;
- private String packedIndexPath;
-
- @Schema(name="skip_packed_index_creation",description = "True, if the packed index will not be created")
- public boolean isSkipPackedIndexCreation( )
- {
- return skipPackedIndexCreation;
- }
-
- public void setSkipPackedIndexCreation( boolean skipPackedIndexCreation )
- {
- this.skipPackedIndexCreation = skipPackedIndexCreation;
- }
-
- @Schema(name="index_path",description = "Path to the index directory relative to the repository base directory")
- public String getIndexPath( )
- {
- return indexPath;
- }
-
- public void setIndexPath( String indexPath )
- {
- this.indexPath = indexPath;
- }
-
- @Schema(name="packed_index_path",description = "Path to the packed index directory relative to the repository base directory")
- public String getPackedIndexPath( )
- {
- return packedIndexPath;
- }
-
- public void setPackedIndexPath( String packedIndexPath )
- {
- this.packedIndexPath = packedIndexPath;
- }
-}
+++ /dev/null
-package org.apache.archiva.rest.api.model.v2.repository;/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.net.URI;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Schema(name="RemoteIndexInfo",description = "Information about remote indexes")
-public class RemoteIndexInfo
-{
- private boolean downloadRemoteIndex = false;
- private String indexUri;
-
- @Schema(name="download_remote_index",description = "True, if the index will be downloaded from the remote repository")
- public boolean isDownloadRemoteIndex( )
- {
- return downloadRemoteIndex;
- }
-
- public void setDownloadRemoteIndex( boolean downloadRemoteIndex )
- {
- this.downloadRemoteIndex = downloadRemoteIndex;
- }
-
- @Schema(name="index_uri", description = "The URI that specifies the path to the remote index")
- public String getIndexUri( )
- {
- return indexUri;
- }
-
- public void setIndexUri( String indexUri )
- {
- this.indexUri = indexUri;
- }
-}
+++ /dev/null
-package org.apache.archiva.rest.api.model.v2.repository;/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import org.apache.archiva.repository.ManagedRepository;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Schema(name="StagingInfo",description = "Information about staging feature of a repository")
-public class StagingInfo
-{
- private String stagingRepository;
- private boolean stageRepoNeeded;
-
- @Schema(name="staging_repo",description = "The repository id of the staging repository")
- public String getStagingRepository( )
- {
- return stagingRepository;
- }
-
- public void setStagingRepository( String stagingRepository )
- {
- this.stagingRepository = stagingRepository;
- }
-
- @Schema(name="stage_repo_needed",description = "True, if this repository needs a staging repository")
- public boolean isStageRepoNeeded( )
- {
- return stageRepoNeeded;
- }
-
- public void setStageRepoNeeded( boolean stageRepoNeeded )
- {
- this.stageRepoNeeded = stageRepoNeeded;
- }
-}
+++ /dev/null
-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.media.Schema;
-import org.apache.archiva.rest.api.model.v2.ValidationError;
-import org.apache.commons.lang3.StringUtils;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @author Martin Stockhammer
- * @since 3.0
- */
-@XmlRootElement( name = "archivaRestError" )
-@Schema(name="ArchivaRestError", description = "Contains a list of error messages that resulted from the current REST call")
-public class ArchivaRestError
- implements Serializable
-{
-
- private static final long serialVersionUID = -8892617571273167067L;
- private List<ErrorMessage> errorMessages = new ArrayList<>( 1 );
- private List<ValidationError> validationErrors;
-
- public ArchivaRestError()
- {
- // no op
- }
-
- public ArchivaRestError( ArchivaRestServiceException e )
- {
- errorMessages.addAll( e.getErrorMessages() );
- if ( e.getErrorMessages().isEmpty() && StringUtils.isNotEmpty( e.getMessage() ) )
- {
- errorMessages.add( new ErrorMessage( e.getMessage(), null ) );
- }
- if (e instanceof ValidationException) {
- this.validationErrors = ( (ValidationException) e ).getValidationErrors( );
- }
- }
-
- public ArchivaRestError( ValidationException e )
- {
- errorMessages.addAll( e.getErrorMessages() );
- if ( e.getErrorMessages().isEmpty() && StringUtils.isNotEmpty( e.getMessage() ) )
- {
- errorMessages.add( new ErrorMessage( e.getMessage(), null ) );
- }
- this.validationErrors = e.getValidationErrors( );
- }
-
- @Schema(name="error_messages", description = "The list of errors that occurred while processing the REST request")
- public List<ErrorMessage> getErrorMessages()
- {
- return errorMessages;
- }
-
- public void setErrorMessages( List<ErrorMessage> errorMessages )
- {
- this.errorMessages = errorMessages;
- }
-
- public void addErrorMessage( ErrorMessage errorMessage )
- {
- this.errorMessages.add( errorMessage );
- }
-
- @Schema( name = "has_validation_errors", description = "True, if the error contains validation errors" )
- public boolean hasValidationErrors( )
- {
- return this.validationErrors != null && this.validationErrors.size( ) > 0;
- }
-
- @Schema( name = "validation_errors", description = "The list of validation errors")
- public List<ValidationError> getValidationErrors() {
- return hasValidationErrors() ? this.validationErrors : Collections.emptyList( );
- }
-}
+++ /dev/null
-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 java.util.ArrayList;
-import java.util.List;
-
-/**
- * Generic REST Service Exception that contains error information.
- *
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-public class ArchivaRestServiceException extends Exception
-{
- private int httpErrorCode = 500;
-
- private List<ErrorMessage> errorMessages = new ArrayList<ErrorMessage>(0);
-
- public ArchivaRestServiceException( String s )
- {
- super( s );
- }
-
- public ArchivaRestServiceException( String s, int httpErrorCode )
- {
- super( s );
- this.httpErrorCode = httpErrorCode;
- }
-
- public ArchivaRestServiceException( ErrorMessage errorMessage )
- {
- errorMessages.add( errorMessage );
- }
-
- public ArchivaRestServiceException( ErrorMessage errorMessage, int httpResponseCode )
- {
- this.httpErrorCode = httpResponseCode;
- errorMessages.add( errorMessage );
- }
-
- public ArchivaRestServiceException( List<ErrorMessage> errorMessage )
- {
- errorMessages.addAll( errorMessage );
- }
-
- public ArchivaRestServiceException( List<ErrorMessage> errorMessage, int httpResponseCode )
- {
- this.httpErrorCode = httpResponseCode;
- errorMessages.addAll( errorMessage );
- }
-
- public int getHttpErrorCode()
- {
- return httpErrorCode;
- }
-
- public void setHttpErrorCode( int httpErrorCode )
- {
- this.httpErrorCode = httpErrorCode;
- }
-
- public List<ErrorMessage> getErrorMessages()
- {
- if ( errorMessages == null )
- {
- this.errorMessages = new ArrayList<ErrorMessage>();
- }
- return errorMessages;
- }
-
- public void setErrorMessages( List<ErrorMessage> errorMessages )
- {
- this.errorMessages = errorMessages;
- }
-
- public void addErrorMessage( ErrorMessage errorMessage )
- {
- this.errorMessages.add( errorMessage );
- }
-
-}
+++ /dev/null
-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.
- */
-
-import org.apache.archiva.rest.api.services.v2.ErrorMessage;
-
-import java.util.List;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-public interface ErrorKeys
-{
-
- String PREFIX = "archiva.";
-
- String VALIDATION_ERROR = PREFIX + "validation_error";
-
- String REPOSITORY_GROUP_PREFIX = PREFIX + "repository_group.";
- String REPOSITORY_PREFIX = PREFIX + "repository.";
-
- String INVALID_RESULT_SET_ERROR = "archiva.result_set.invalid";
- String REPOSITORY_ADMIN_ERROR = "archiva.repositoryadmin.error";
- String LDAP_CF_INIT_FAILED = "archiva.ldap.cf.init.failed";
- String LDAP_USER_MAPPER_INIT_FAILED = "archiva.ldap.usermapper.init.failed";
- String LDAP_COMMUNICATION_ERROR = "archiva.ldap.communication_error";
- String LDAP_INVALID_NAME = "archiva.ldap.invalid_name";
- String LDAP_GENERIC_ERROR = "archiva.ldap.generic_error";
- String LDAP_SERVICE_UNAVAILABLE = "archiva.ldap.service_unavailable";
- String LDAP_SERVICE_AUTHENTICATION_FAILED = "archiva.ldap.authentication.failed";
- String LDAP_SERVICE_AUTHENTICATION_NOT_SUPPORTED = "archiva.ldap.authentication.not_supported";
- String LDAP_SERVICE_NO_PERMISSION = "archiva.ldap.no_permissions";
-
- String PROPERTY_NOT_FOUND = "archiva.property.not.found";
-
- String MISSING_DATA = "archiva.missing.data";
-
- 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_UPDATE_FAILED = REPOSITORY_GROUP_PREFIX + "update.failed";
-
- String REPOSITORY_GROUP_DELETE_FAILED = REPOSITORY_GROUP_PREFIX + "delete.failed";
- String REPOSITORY_NOT_FOUND = REPOSITORY_PREFIX + "notfound";
- String REPOSITORY_MANAGED_NOT_FOUND = REPOSITORY_PREFIX + "managed.notfound";
- String REPOSITORY_REMOTE_NOT_FOUND = REPOSITORY_PREFIX + "remote.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";
- String ARTIFACT_EXISTS_AT_DEST = REPOSITORY_PREFIX + "artifact.dest.exists";
- String REPOSITORY_REMOTE_INDEX_DOWNLOAD_FAILED = REPOSITORY_PREFIX + "remote.index.download_failed";
- String REPOSITORY_WRONG_TYPE = REPOSITORY_PREFIX + "wrong_type";
- String REPOSITORY_DELETE_FAILED = REPOSITORY_PREFIX + "delete.failed";
- String REPOSITORY_INVALID_ID = REPOSITORY_PREFIX + "invalid.id";
- String REPOSITORY_ID_EXISTS = REPOSITORY_PREFIX + "id.exists";
- String REPOSITORY_UPDATE_FAILED = REPOSITORY_PREFIX + "update.failed";
- String ARTIFACT_NOT_FOUND = REPOSITORY_PREFIX + "artifact.notfound";
- String REPOSITORY_LAYOUT_ERROR = REPOSITORY_PREFIX + "layout.error";
-
- String ARTIFACT_COPY_ERROR = REPOSITORY_PREFIX + "artifact.copy.error";
-
- /**
- * The given user was not found
- * Parameters:
- * - User Id
- */
- String USER_NOT_FOUND = PREFIX+"user.not_found";
-
- /**
- * Error from UserManager
- * Parameters:
- * - Error Message
- */
- String USER_MANAGER_ERROR = PREFIX+"user_manager.error";
-
- /**
- * Permission to the repository denied.
- * Parameters:
- * - Repository Id
- * - Permission ID
- */
- String PERMISSION_REPOSITORY_DENIED = PREFIX + "permission.repository.denied";
-
- /**
- * A generic authorization error thrown during the authorization check.
- * Parameters:
- * - Error message
- */
- String AUTHORIZATION_ERROR = PREFIX + "authorization.error";
-
- /**
- * When the operation needs authentication, but not authenticated user was found in the request context.
- */
- String NOT_AUTHENTICATED = PREFIX + "user.not_authenticated";
-}
+++ /dev/null
-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.media.Schema;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-
-/**
- * @author Olivier Lamy
- * @author Martin Stockhammer
- * @since 3.0
- */
-@XmlRootElement( name = "errorMessage" )
-@Schema(name="ErrorMessage",description = "Information about the error, that occurred while processing the REST request.")
-public class ErrorMessage
- implements Serializable
-{
- private String errorKey = "";
-
- private String[] args = EMPTY;
-
- private String message = "";
-
- private static final String[] EMPTY = new String[0];
-
- public ErrorMessage()
- {
- // no op
- }
-
- public ErrorMessage( String errorKey )
- {
- this.errorKey = errorKey;
- this.args = EMPTY;
- }
-
- public ErrorMessage( String errorKey, String[] args )
- {
- this.errorKey = errorKey;
- this.args = args;
- }
-
- public static ErrorMessage of(String errorKey, String... args) {
- return new ErrorMessage( errorKey, args );
- }
-
- @Schema(name="error_key", description = "The key of the error message. If this is empty, the message message must be set.")
- public String getErrorKey()
- {
- return errorKey;
- }
-
- public void setErrorKey( String errorKey )
- {
- this.errorKey = errorKey;
- }
-
- @Schema(description = "Parameters that can be filled to the translated error message")
- public String[] getArgs()
- {
- return args;
- }
-
- public void setArgs( String[] args )
- {
- this.args = args;
- }
-
- @Schema(description = "Full error message. Either additional to the key in the default language, or if the message is without key.")
- public String getMessage()
- {
- return message;
- }
-
- public void setMessage( String message )
- {
- this.message = message;
- }
-
- public ErrorMessage message( String message )
- {
- this.message = message;
- return this;
- }
-}
+++ /dev/null
-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.parameters.RequestBody;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.security.SecurityRequirement;
-import org.apache.archiva.components.rest.model.PagedResult;
-import org.apache.archiva.redback.authorization.RedbackAuthorization;
-import org.apache.archiva.rest.api.model.v2.RepositoryGroup;
-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.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;
-
-/**
- * Endpoint for repository groups that combine multiple repositories into a single virtual repository.
- *
- * @author Olivier Lamy
- * @author Martin Stockhammer
- * @since 3.0
- */
-@Path( "/repository_groups" )
-@Schema( name = "RepositoryGroups", description = "Managing of repository groups or virtual repositories" )
-public interface RepositoryGroupService
-{
- @Path( "" )
- @GET
- @Produces( {APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Returns all repository group entries.",
- 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<RepositoryGroup> getRepositoriesGroups( @QueryParam( "q" ) @DefaultValue( "" ) String searchTerm,
- @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
- @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
- @QueryParam( "orderBy" ) @DefaultValue( "id" ) List<String> orderBy,
- @QueryParam( "order" ) @DefaultValue( "asc" ) String order )
- throws ArchivaRestServiceException;
-
- @Path( "{id}" )
- @GET
- @Produces( {APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Returns a single repository group configuration.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the configuration is returned",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.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 group with the given id does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- RepositoryGroup getRepositoryGroup( @PathParam( "id" ) String repositoryGroupId )
- throws ArchivaRestServiceException;
-
- @Path( "" )
- @POST
- @Consumes( {APPLICATION_JSON} )
- @Produces( {APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Creates a new group entry.",
- requestBody =
- @RequestBody( required = true, description = "The configuration of the repository group.",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.class ) )
- )
- ,
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "201",
- description = "If the repository group was created",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.class ) )
- ),
- @ApiResponse( responseCode = "303", description = "The repository group exists already",
- headers = {
- @Header( name = "Location", description = "The URL of existing group", schema = @Schema( type = "string" ) )
- }
- ),
- @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 = "422", description = "The body data is not valid",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- RepositoryGroup addRepositoryGroup( RepositoryGroup repositoryGroup )
- throws ArchivaRestServiceException;
-
- @Path( "{id}" )
- @PUT
- @Consumes( {APPLICATION_JSON} )
- @Produces( {APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Returns all repository group entries.",
- requestBody =
- @RequestBody( required = true, description = "The configuration of the repository group.",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.class ) )
- )
- ,
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the group is returned",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.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 group with the given id does not exist",
- 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 ) ) )
- }
- )
- RepositoryGroup updateRepositoryGroup( @PathParam( "id" ) String groupId, RepositoryGroup repositoryGroup )
- throws ArchivaRestServiceException;
-
- @Path( "{id}" )
- @DELETE
- @Produces( {APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Deletes the repository group entry with the given id.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the group was deleted"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete the group",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The group with the given id does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- }
- )
- Response deleteRepositoryGroup( @PathParam( "id" ) String repositoryGroupId )
- throws ArchivaRestServiceException;
-
- @Path( "{id}/repositories/{repositoryId}" )
- @PUT
- @Produces( {APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Adds the repository with the given id to the repository group.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the repository was added or if it was already part of the group"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete the group",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The group with the given id does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- }
- )
- RepositoryGroup addRepositoryToGroup( @PathParam( "id" ) String repositoryGroupId,
- @PathParam( "repositoryId" ) String repositoryId )
- throws ArchivaRestServiceException;
-
- @Path( "{id}/repositories/{repositoryId}" )
- @DELETE
- @Produces( {APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Removes the repository with the given id from the repository group.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the repository was removed."
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete the group",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "Either the group with the given id does not exist, or the repository was not part of the group.",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- }
- )
- RepositoryGroup deleteRepositoryFromGroup( @PathParam( "id" ) String repositoryGroupId,
- @PathParam( "repositoryId" ) String repositoryId )
- throws ArchivaRestServiceException;
-
-
-}
+++ /dev/null
-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.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.Context;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import java.util.List;
-
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static org.apache.archiva.rest.api.services.v2.RestConfiguration.DEFAULT_PAGE_LIMIT;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-@Path( "repositories" )
-@Tag(name = "v2")
-@Tag(name = "v2/Repositories")
-@Schema(name="RepositoryService",description = "Manage repositories of all types")
-public interface RepositoryService
-{
-
- @Path( "" )
- @GET
- @Produces( {APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Returns all managed repositories.",
- parameters = {
- @Parameter( name = "q", description = "Search term" ),
- @Parameter( name = "offset", description = "The offset of the first element returned" ),
- @Parameter( name = "limit", description = "Maximum number of items to return in the response" ),
- @Parameter( name = "orderBy", description = "List of attribute used for sorting (key, value)" ),
- @Parameter( name = "order", description = "The sort order. Either ascending (asc) or descending (desc)" ),
- @Parameter( name = "locale", description = "The locale for name and description" )
- },
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the list could be returned",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = PagedResult.class ) )
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- PagedResult<Repository> getRepositories( @QueryParam( "q" ) @DefaultValue( "" ) String searchTerm,
- @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
- @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
- @QueryParam( "orderBy" ) @DefaultValue( "id" ) List<String> orderBy,
- @QueryParam( "order" ) @DefaultValue( "asc" ) String order,
- @QueryParam( "locale" ) String localeString) throws ArchivaRestServiceException;
-
- @Path( "managed/{id}/statistics" )
- @GET
- @Produces( {APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Returns repository statistic data.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the statistics could be returned",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryStatistics.class ) )
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The repository does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- RepositoryStatistics getManagedRepositoryStatistics( @PathParam( "id" ) String repositoryId )
- throws ArchivaRestServiceException;
-
- @Path ("managed/{id}/scan/schedule")
- @POST
- @Produces ({ APPLICATION_JSON })
- @Consumes({ APPLICATION_JSON })
- @RedbackAuthorization (permissions = ArchivaRoleConstants.OPERATION_RUN_INDEXER)
- @Operation( summary = "Returns repository statistic data.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the statistics could be returned"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The repository does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- Response scheduleRepositoryScan( @PathParam ("id") String repositoryId,
- @QueryParam ("fullScan") boolean fullScan )
- throws ArchivaRestServiceException;
-
-
- @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;
-
-
- @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 = "Cancels and removes all tasks for the given repository.",
- 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;
-
-
-
- @Path ("remote/{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.",
- parameters = {
- @Parameter( name = "full", description = "If true, download the full index, otherwise try a update 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( "immediate" ) boolean immediately,
- @QueryParam ("full") boolean full, @Context UriInfo uriInfo )
- throws ArchivaRestServiceException;
-
-
- @Path ("remote/index/downloads")
- @GET
- @Produces ({ APPLICATION_JSON })
- @RedbackAuthorization (permissions = ArchivaRoleConstants.OPERATION_RUN_INDEXER)
- @Operation( summary = "Returns a list of running downloads from the remote repository.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the artifact was deleted"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- List<String> getRunningRemoteDownloads();
-
-
-}
+++ /dev/null
-package org.apache.archiva.rest.api.services.v2;/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-public interface RestConfiguration
-{
- String DEFAULT_PAGE_LIMIT = "10";
-}
+++ /dev/null
-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.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.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.components.rest.model.PropertyEntry;
-import org.apache.archiva.redback.authorization.RedbackAuthorization;
-import org.apache.archiva.rest.api.model.v2.BeanInformation;
-import org.apache.archiva.rest.api.model.v2.CacheConfiguration;
-import org.apache.archiva.rest.api.model.v2.LdapConfiguration;
-import org.apache.archiva.rest.api.model.v2.SecurityConfiguration;
-import org.apache.archiva.security.common.ArchivaRoleConstants;
-
-import javax.ws.rs.Consumes;
-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.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;
-
-/**
- *
- * Service for configuration of redback and security related settings.
- *
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-@Path( "/security" )
-@Tag(name = "v2")
-@Tag(name = "v2/Security")
-@SecurityRequirement(name = "BearerAuth")
-public interface SecurityConfigurationService
-{
- @Path("config")
- @GET
- @Produces({ APPLICATION_JSON })
- @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
- @Operation( summary = "Returns the security configuration that is currently active.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the configuration could be retrieved",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = SecurityConfiguration.class))
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
- }
- )
- SecurityConfiguration getConfiguration()
- throws ArchivaRestServiceException;
-
- @Path("config")
- @PUT
- @Consumes({ APPLICATION_JSON })
- @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
- @Operation( summary = "Updates the security configuration.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the configuration was updated"
- ),
- @ApiResponse( responseCode = "422", description = "Invalid content data",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to update the configuration",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
- }
- )
- SecurityConfiguration updateConfiguration( SecurityConfiguration newConfiguration)
- throws ArchivaRestServiceException;
-
-
- @Path( "config/properties" )
- @GET
- @Produces( { APPLICATION_JSON } )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Returns all configuration properties. The result is paged.",
- 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<PropertyEntry> getConfigurationProperties( @QueryParam("q") @DefaultValue( "" ) String searchTerm,
- @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
- @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
- @QueryParam( "orderBy") @DefaultValue( "key" ) List<String> orderBy,
- @QueryParam("order") @DefaultValue( "asc" ) String order ) throws ArchivaRestServiceException;
-
- @Path("config/properties/{propertyName}")
- @GET
- @Produces({ APPLICATION_JSON })
- @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
- @Operation( summary = "Returns a single configuration property value.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- parameters = {
- @Parameter(in = ParameterIn.PATH, name="propertyName", description = "The name of the property to get the value for")
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the configuration could be retrieved",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = PropertyEntry.class))
- ),
- @ApiResponse( responseCode = "404", description = "The given property name does not exist",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
- }
- )
- PropertyEntry getConfigurationProperty( @PathParam ( "propertyName" ) String propertyName)
- throws ArchivaRestServiceException;
-
-
- @Path("config/properties/{propertyName}")
- @PUT
- @Consumes({ APPLICATION_JSON})
- @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
- @Operation( summary = "Updates a single property value of the security configuration.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- parameters = {
- @Parameter(in = ParameterIn.PATH, name="propertyName", description = "The name of the property to update")
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the property value was updated."
- ),
- @ApiResponse( responseCode = "400", description = "The body data is not valid",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
- @ApiResponse( responseCode = "404", description = "The given property name does not exist",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
- }
- )
- Response updateConfigurationProperty( @PathParam ( "propertyName" ) String propertyName, PropertyEntry propertyValue)
- throws ArchivaRestServiceException;
-
- @Path("config/ldap")
- @GET
- @Produces({ APPLICATION_JSON })
- @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
- @Operation( summary = "Returns the LDAP configuration that is currently active.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the configuration could be retrieved",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = LdapConfiguration.class))
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
- }
- )
- LdapConfiguration getLdapConfiguration( ) throws ArchivaRestServiceException;
-
- @Path("config/ldap")
- @PUT
- @Consumes({ APPLICATION_JSON })
- @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
- @Operation( summary = "Updates the LDAP configuration that is currently active.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the configuration was updated"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to update the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
- }
- )
- LdapConfiguration updateLdapConfiguration( LdapConfiguration configuration ) throws ArchivaRestServiceException;
-
- @Path("config/ldap/verify")
- @POST
- @Consumes({ APPLICATION_JSON })
- @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
- @Operation( summary = "Checks the given LDAP configuration.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the check was successful"
- ),
- @ApiResponse( responseCode = "400",
- description = "If the check was not successful",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class ))
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to update the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
- }
- )
- Response verifyLdapConfiguration( LdapConfiguration configuration ) throws ArchivaRestServiceException;
-
- @Path("config/cache")
- @GET
- @Produces({ APPLICATION_JSON })
- @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
- @Operation( summary = "Returns the cache configuration that is currently active.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the configuration could be retrieved",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = CacheConfiguration.class))
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
- }
- )
- CacheConfiguration getCacheConfiguration( ) throws ArchivaRestServiceException;
-
- @Path("config/cache")
- @PUT
- @Consumes({ APPLICATION_JSON })
- @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
- @Operation( summary = "Updates the LDAP configuration that is currently active.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the configuration was updated"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to update the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
- }
- )
- CacheConfiguration updateCacheConfiguration( CacheConfiguration cacheConfiguration ) throws ArchivaRestServiceException;
-
-
- @Path("user_managers")
- @GET
- @Produces({ APPLICATION_JSON })
- @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
- @Operation( summary = "Returns the available user manager implementations.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the list could be retrieved",
- content = @Content(mediaType = APPLICATION_JSON, array = @ArraySchema(
- schema = @Schema(implementation = BeanInformation.class)))
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
- }
- )
- List<BeanInformation> getAvailableUserManagers()
- throws ArchivaRestServiceException;
-
- @Path("rbac_managers")
- @GET
- @Produces({ APPLICATION_JSON })
- @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
- @Operation( summary = "Returns the available RBAC manager implementations.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the list could be retrieved",
- content = @Content(mediaType = APPLICATION_JSON, array = @ArraySchema(
- schema = @Schema(implementation = BeanInformation.class)))
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
- }
- )
- List<BeanInformation> getAvailableRbacManagers()
- throws ArchivaRestServiceException;
-
-}
+++ /dev/null
-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 org.apache.archiva.repository.Repository;
-import org.apache.archiva.repository.validation.ValidationResponse;
-import org.apache.archiva.rest.api.model.v2.ValidationError;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * Exception is thrown
- *
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-public class ValidationException extends ArchivaRestServiceException
-{
- public static final int DEFAULT_CODE = 422;
-
- public static final ErrorMessage DEFAULT_MESSAGE = new ErrorMessage( ErrorKeys.VALIDATION_ERROR );
-
- private List<ValidationError> validationErrors;
-
- public ValidationException( )
- {
- super( DEFAULT_MESSAGE, DEFAULT_CODE );
- }
-
- public ValidationException( int errorCode )
- {
- super( DEFAULT_MESSAGE, errorCode );
- }
-
- public ValidationException( List<ValidationError> errors )
- {
- super( DEFAULT_MESSAGE, DEFAULT_CODE );
- this.validationErrors = errors;
- }
-
- public static ValidationException of( List<org.apache.archiva.repository.validation.ValidationError> errorList )
- {
- return new ValidationException( errorList.stream( ).map( ValidationError::of ).collect( Collectors.toList( ) ) );
- }
-
- public static ValidationException of( Map<String, List<org.apache.archiva.repository.validation.ValidationError>> errorMap )
- {
- return new ValidationException( errorMap.entrySet( ).stream( )
- .flatMap( v -> v.getValue( ).stream( ).map( k -> ValidationError.of(v.getKey(), k)))
- .collect( Collectors.toList( ) ) );
- }
-
- public static <R extends Repository> ValidationException of( ValidationResponse<R> result )
- {
- if ( result.isValid( ) )
- {
- return new ValidationException( );
- }
- else
- {
- return new ValidationException( result.getResult( ).entrySet( ).stream( ).flatMap(
- v -> v.getValue( ).stream( ).map( e -> ValidationError.of( v.getKey( ), e ) ) ).collect( Collectors.toList( ) ) );
- }
- }
-
- public List<ValidationError> getValidationErrors( )
- {
- return validationErrors == null ? Collections.emptyList( ) : validationErrors;
- }
-
- public void setValidationErrors( List<ValidationError> validationErrors )
- {
- this.validationErrors = validationErrors;
- }
-
- public void addValidationError( ValidationError error )
- {
- if ( this.validationErrors == null )
- {
- this.validationErrors = new ArrayList<>( );
- }
- this.validationErrors.add( error );
- }
-}
+++ /dev/null
-package org.apache.archiva.rest.api.services.v2.maven;
-/*
- * 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.OAuthScope;
-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.rest.api.model.v2.MavenManagedRepositoryUpdate;
-import org.apache.archiva.rest.api.services.v2.ArchivaRestError;
-import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
-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;
-
-/**
- * Service interface for managing managed maven repositories
- *
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-@Schema( name = "ManagedRepositoryService", description = "Managing and configuration of managed repositories" )
-@Path( "repositories/maven/managed" )
-@Tag(name = "v2")
-@Tag(name = "v2/Repositories")
-public interface MavenManagedRepositoryService
-{
- @Path( "" )
- @GET
- @Produces( {APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Returns all managed repositories.",
- parameters = {
- @Parameter( name = "q", description = "Search term" ),
- @Parameter( name = "offset", description = "The offset of the first element returned" ),
- @Parameter( name = "limit", description = "Maximum number of items to return in the response" ),
- @Parameter( name = "orderBy", description = "List of attribute used for sorting (key, value)" ),
- @Parameter( name = "order", description = "The sort order. Either ascending (asc) or descending (desc)" )
- },
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the list could be returned",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = PagedResult.class ) )
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- PagedResult<MavenManagedRepository> getManagedRepositories(
- @QueryParam( "q" ) @DefaultValue( "" ) String searchTerm,
- @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
- @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
- @QueryParam( "orderBy" ) @DefaultValue( "id" ) List<String> orderBy,
- @QueryParam( "order" ) @DefaultValue( "asc" ) String order )
- throws ArchivaRestServiceException;
-
-
- @Path( "{id}" )
- @GET
- @Produces( {MediaType.APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Returns the managed repository with the given id.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the managed repository could be returned",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- MavenManagedRepository getManagedRepository( @PathParam( "id" ) String repositoryId )
- throws ArchivaRestServiceException;
-
-
- @Path( "{id}" )
- @DELETE
- @Produces( {MediaType.APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Deletes the managed repository with the given id.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the managed repository could be returned"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- Response deleteManagedRepository( @PathParam( "id" ) String repositoryId,
- @QueryParam( "deleteContent" ) boolean deleteContent )
- throws ArchivaRestServiceException;
-
-
- @Path( "" )
- @POST
- @Consumes( {MediaType.APPLICATION_JSON} )
- @Produces( {MediaType.APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Creates the managed repository",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "201",
- description = "If the managed repository could be created",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
- ),
- @ApiResponse( responseCode = "303", description = "The repository exists already",
- headers = {
- @Header( name = "Location", description = "The URL of existing repository ", schema = @Schema( type = "string" ) )
- }
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "422", description = "The body data is not valid",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- MavenManagedRepository addManagedRepository( MavenManagedRepository managedRepository )
- throws ArchivaRestServiceException;
-
-
- @Path( "{id}" )
- @PUT
- @Consumes( {MediaType.APPLICATION_JSON} )
- @Produces( {MediaType.APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Updates the managed repository with the given id",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the managed repository could be updated",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "422", description = "The body data is not valid",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- MavenManagedRepository updateManagedRepository( @PathParam( "id" ) String repositoryId, MavenManagedRepositoryUpdate managedRepository )
- throws ArchivaRestServiceException;
-
-
- @Path( "{id}/path/{filePath: .+}" )
- @GET
- @Produces( {MediaType.APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS, resource = "{id}")
- @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;
-
-
- /**
- * Permissions are checked in impl
- * will copy an artifact from the source repository to the target repository
- */
- @Path ("{srcId}/path/{path: .+}/copyto/{dstId}")
- @POST
- @Produces({APPLICATION_JSON})
- @RedbackAuthorization (noPermission = true)
- @Operation( summary = "Copies a artifact from the source repository to the destination repository",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
- scopes = {
- "{srcId}"
- }
- ),
- @SecurityRequirement(
- name= ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD,
- scopes = {
- "{dstId}"
- }
- )
-
- },
- 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( @PathParam( "srcId" ) String srcRepositoryId, @PathParam( "dstId" ) String dstRepositoryId,
- @PathParam( "path" ) String path )
- throws ArchivaRestServiceException;
-
-
- @Path ("{id}/path/{path: .+}")
- @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( @PathParam( "id" ) String repositoryId, @PathParam( "path" ) String path )
- throws ArchivaRestServiceException;
-
- @Path ( "{id}/co/{group}/{project}/{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 ( "group" ) String namespace, @PathParam ( "project" ) String projectId,
- @PathParam ( "version" ) String version )
- throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
-
-
- @Path ( "{id}/co/{group}/{project}" )
- @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 ( "group" ) String namespace, @PathParam ( "project" ) String projectId )
- throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
-
- @Path ( "{id}/co/{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;
-
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * <p>This is the V2 REST API of Archiva. It uses JAX-RS annotations for defining the endpoints.
- * The API is documented with OpenApi annotations.</p>
- *
- * <h3>Some design principles of the API and classes:</h3>
- * <ul>
- * <li>All services use V2 model classes. Internal models are always converted to V2 classes.</li>
- * <li>Schema attributes use the snake case syntax (lower case with '_' as divider)</li>
- * <li>Return code <code>200</code> and <code>201</code> (POST) is used for successful execution.</li>
- * <li>Return code <code>403</code> is used, if the user has not the permission for the action.</li>
- * <li>Return code <code>422</code> is used for input that has invalid data.</li>
- * </ul>
- *
- * <h4>Querying entity lists</h4>
- * <p>The main entities of a given path are retrieved on the base path.
- * Further sub entities or entries may be retrieved via subpaths.
- * A single entity is returned by the "{id}" path. Be careful with technical paths that are parallel to the
- * id path. Avoid naming conflicts with the id and technical paths.
- * Entity attributes may be retrieved by "{id}/{attribute}" path or if there are lists or collections by
- * "{id}/mycollection/{subentryid}"</p>
- *
- * <ul>
- * <li><code>GET</code> method is used for retrieving entities on the base path ""</li>
- * <li>The query for base entities should always return a paged result and be filterable and sortable</li>
- * <li>Query parameters for filtering, ordering and limits should be optional and proper defaults must be set</li>
- * <li>Return code <code>200</code> is used for successful retrieval</li>
- * <li>This action is idempotent</li>
- * </ul>
- *
- * <h4>Querying single entities</h4>
- * <p>Single entities are retrieved on the path "{id}"</p>
- * <ul>
- * <li><code>GET</code> method is used for retrieving a single entity. The id is always a path parameter.</li>
- * <li>Return code <code>200</code> is used for successful retrieval</li>
- * <li>Return code <code>404</code> is used if the entity with the given id does not exist</li>
- * <li>This action is idempotent</li>
- * </ul>
- *
- * <h4>Creating entities</h4>
- * <p>The main entities are created on the base path "".</p>
- * <ul>
- * <li><code>POST</code> is used for creating new entities</li>
- * <li>The <code>POST</code> body must always have a complete definition of the entity.</li>
- * <li>A unique <code>id</code> or <code>name</code> attribute is required for entities. If the id is generated during POST,
- * it must be returned by response body.</li>
- * <li>A successful <code>POST</code> request should always return the entity definition as it would be returned by the GET request.</li>
- * <li>Return code <code>201</code> is used for successful creation of the new entity.</li>
- * <li>A successful response has a <code>Location</code> header with the URL for retrieving the single created entity.</li>
- * <li>Return code <code>303</code> is used, if the entity exists already</li>
- * <li>This action is not idempotent</li>
- * </ul>
- *
- * <h4>Updating entities</h4>
- * <p>The path for entity update must contain the '{id}' of the entity. The path should be the same as for the GET operation.</p>
- * <ul>
- * <li><code>PUT</code> is used for updating existing entities</li>
- * <li>The body contains a JSON object. Only existing attributes are updated.</li>
- * <li>A successful PUT request should return the complete entity definition as it would be returned by the GET request.</li>
- * <li>Return code <code>200</code> is used for successful update of the new entity. Even if nothing changed.</li>
- * <li>This action is idempotent</li>
- * </ul>
- *
- * <h4>Deleting entities</h4>
- * <p>The path for entity deletion must contain the '{id}' of the entity. The path should be the same as
- * for the GET operation.</p>
- * <ul>
- * <li><code>DELETE</code> is used for deleting existing entities</li>
- * <li>The successful operation has no request and no response body</li>
- * <li>Return code <code>200</code> is used for successful deletion of the new entity.</li>
- * <li>This action is not idempotent</li>
- * </ul>
- *
- * <h4>Errors</h4>
- * <ul>
- * <li>A error uses a return code <code>>=400</code> </li>
- * <li>All errors use the same result object ({@link org.apache.archiva.rest.api.services.v2.ArchivaRestError}</li>
- * <li>Error messages are returned as keys. Translation is part of the client application.</li>
- * </ul>
- *
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-package org.apache.archiva.rest.api.services.v2;
\ No newline at end of file
--- /dev/null
+package org.apache.archiva.rest.api.v2.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 io.swagger.v3.oas.annotations.media.Schema;
+
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="Artifact", description = "Information about artifacts")
+public class Artifact implements Serializable
+{
+ private static final long serialVersionUID = 7581578317346876555L;
+ private String name;
+
+ @Schema(name="name",description = "The name of the artifact")
+ public String getName( )
+ {
+ return name;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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 io.swagger.v3.oas.annotations.media.Schema;
+
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class ArtifactTransferRequest implements Serializable
+{
+ private static final long serialVersionUID = -7377281345536573342L;
+
+ private String path;
+
+ @Schema(description = "The path to the artifact")
+ public String getPath( )
+ {
+ return path;
+ }
+
+ public void setPath( String path )
+ {
+ this.path = path;
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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.
+ */
+
+/*
+ * 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.Objects;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@XmlRootElement(name="beanInformation")
+@Schema(name="BeanInformation",description = "Information about a bean instance.")
+public class BeanInformation implements Serializable
+{
+ private static final long serialVersionUID = -432385743277355987L;
+ private String id;
+ private String displayName;
+ private String descriptionKey;
+ private String defaultDescription;
+ private boolean readonly;
+
+ public BeanInformation( )
+ {
+ }
+
+ public BeanInformation( String id, String displayName, String descriptionKey, String defaultDescription, boolean readonly )
+ {
+ this.id = id;
+ this.displayName = displayName;
+ this.descriptionKey = descriptionKey;
+ this.defaultDescription = defaultDescription;
+ this.readonly = readonly;
+ }
+
+ @Schema(description = "The identifier")
+ public String getId( )
+ {
+ return id;
+ }
+
+ public void setId( String id )
+ {
+ this.id = id;
+ }
+
+ @Schema(name="display_name", description = "The display name")
+ public String getDisplayName( )
+ {
+ return displayName;
+ }
+
+ public void setDisplayName( String displayName )
+ {
+ this.displayName = displayName;
+ }
+
+ @Schema(name="description_key", description = "The translation key for the description")
+ public String getDescriptionKey( )
+ {
+ return descriptionKey;
+ }
+
+ public void setDescriptionKey( String descriptionKey )
+ {
+ this.descriptionKey = descriptionKey;
+ }
+
+ @Schema(name="default_description", description = "The description translated in the default language")
+ public String getDefaultDescription( )
+ {
+ return defaultDescription;
+ }
+
+ public void setDefaultDescription( String defaultDescription )
+ {
+ this.defaultDescription = defaultDescription;
+ }
+
+ @Schema(description = "True, if this bean cannot be removed")
+ public boolean isReadonly( )
+ {
+ return readonly;
+ }
+
+ public void setReadonly( boolean readonly )
+ {
+ this.readonly = readonly;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+ BeanInformation that = (BeanInformation) o;
+ return readonly == that.readonly && id.equals( that.id ) && Objects.equals( displayName, that.displayName ) && Objects.equals( descriptionKey, that.descriptionKey ) && Objects.equals( defaultDescription, that.defaultDescription );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ return Objects.hash( id, displayName, descriptionKey, defaultDescription, readonly );
+ }
+
+ @Override
+ public String toString( )
+ {
+ return "BeanInformation{" +
+ "id='" + id + '\'' +
+ ", display_name='" + displayName + '\'' +
+ ", description_key='" + descriptionKey + '\'' +
+ ", default_description='" + defaultDescription + '\'' +
+ ", readonly=" + readonly +
+ '}';
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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 io.swagger.v3.oas.annotations.media.Schema;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+
+/**
+ * @author Olivier Lamy
+ * @author Martin Stockhammer
+ * @since 3.0
+ */
+@XmlRootElement( name = "cacheConfiguration" )
+@Schema(name="CacheConfiguration",description = "Cache configuration attributes")
+public class CacheConfiguration
+ implements Serializable
+{
+ private static final long serialVersionUID = 5479989049980673894L;
+ /**
+ * TimeToIdleSeconds.
+ */
+ private int timeToIdleSeconds = -1;
+
+ /**
+ * TimeToLiveSeconds.
+ */
+ private int timeToLiveSeconds = -1;
+
+ /**
+ * max elements in memory.
+ */
+ private int maxEntriesInMemory = -1;
+
+ /**
+ * max elements on disk.
+ */
+ private int maxEntriesOnDisk = -1;
+
+ public CacheConfiguration()
+ {
+ // no op
+ }
+
+ public static CacheConfiguration of( org.apache.archiva.admin.model.beans.CacheConfiguration beanConfiguration ) {
+ CacheConfiguration newConfig = new CacheConfiguration( );
+ newConfig.setMaxEntriesInMemory( beanConfiguration.getMaxElementsInMemory() );
+ newConfig.setMaxEntriesOnDisk( beanConfiguration.getMaxElementsOnDisk() );
+ newConfig.setTimeToIdleSeconds( beanConfiguration.getTimeToIdleSeconds( ) );
+ newConfig.setTimeToLiveSeconds( beanConfiguration.getTimeToLiveSeconds( ) );
+ return newConfig;
+ }
+
+ @Schema(name="time_to_idle_seconds", description = "The maximum number of seconds an element can exist in the cache without being accessed. "+
+ "The element expires at this limit and will no longer be returned from the cache.")
+ public int getTimeToIdleSeconds()
+ {
+ return timeToIdleSeconds;
+ }
+
+ public void setTimeToIdleSeconds( int timeToIdleSeconds )
+ {
+ this.timeToIdleSeconds = timeToIdleSeconds;
+ }
+
+ @Schema(name="time_to_live_seconds", description = "The maximum number of seconds an element can exist in the cache regardless of use. "+
+ "The element expires at this limit and will no longer be returned from the cache.")
+ public int getTimeToLiveSeconds()
+ {
+ return timeToLiveSeconds;
+ }
+
+ public void setTimeToLiveSeconds( int timeToLiveSeconds )
+ {
+ this.timeToLiveSeconds = timeToLiveSeconds;
+ }
+
+ @Schema(name="max_entries_in_memory", description = "The maximum cache entries to keep in memory. If the limit is reached, older entries will be evicted, or persisted on disk.")
+ public int getMaxEntriesInMemory()
+ {
+ return maxEntriesInMemory;
+ }
+
+ public void setMaxEntriesInMemory( int maxEntriesInMemory )
+ {
+ this.maxEntriesInMemory = maxEntriesInMemory;
+ }
+
+ @Schema(name="max_entries_on_disk", description = "The maximum cache entries to keep on disk. If the limit is reached, older entries will be evicted.")
+ public int getMaxEntriesOnDisk()
+ {
+ return maxEntriesOnDisk;
+ }
+
+ public void setMaxEntriesOnDisk( int maxEntriesOnDisk )
+ {
+ this.maxEntriesOnDisk = maxEntriesOnDisk;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ CacheConfiguration that = (CacheConfiguration) o;
+
+ if ( timeToIdleSeconds != that.timeToIdleSeconds ) return false;
+ if ( timeToLiveSeconds != that.timeToLiveSeconds ) return false;
+ if ( maxEntriesInMemory != that.maxEntriesInMemory ) return false;
+ return maxEntriesOnDisk == that.maxEntriesOnDisk;
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = timeToIdleSeconds;
+ result = 31 * result + timeToLiveSeconds;
+ result = 31 * result + maxEntriesInMemory;
+ result = 31 * result + maxEntriesOnDisk;
+ return result;
+ }
+
+ @Override
+ public String toString()
+ {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "CacheConfiguration" );
+ sb.append( "{time_to_idle_seconds=" ).append( timeToIdleSeconds );
+ sb.append( ", time_to_live_seconds=" ).append( timeToLiveSeconds );
+ sb.append( ", max_elements_in_memory=" ).append( maxEntriesInMemory );
+ sb.append( ", max_elements_on_disk=" ).append( maxEntriesOnDisk );
+ sb.append( '}' );
+ return sb.toString();
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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.
+ */
+
+/*
+ * 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.storage.StorageAsset;
+
+import java.io.Serializable;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="FileInfo",description = "Information about a file stored in the repository")
+public class FileInfo implements Serializable
+{
+ private static final long serialVersionUID = 900497784542880195L;
+ private OffsetDateTime modified;
+ private String fileName;
+ private String path;
+
+ public FileInfo( )
+ {
+ }
+
+ public static FileInfo of( StorageAsset asset ) {
+ FileInfo fileInfo = new FileInfo( );
+ fileInfo.setFileName( asset.getName() );
+ fileInfo.setPath( asset.getPath() );
+ fileInfo.setModified( asset.getModificationTime( ).atOffset( ZoneOffset.UTC ) );
+ return fileInfo;
+ }
+
+ @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( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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 io.swagger.v3.oas.annotations.media.Schema;
+
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="IndexingTask",description = "Information about indexing tasks")
+public class IndexingTask implements Serializable
+{
+ private static final long serialVersionUID = -1947200162602613310L;
+ private String repositoryId = "";
+ private boolean fullRepository;
+ private boolean updateOnly;
+ private String resource = "";
+ private boolean running = false;
+ private long maxExecutionTimeMs = 0;
+
+ public static IndexingTask of( org.apache.archiva.admin.model.beans.IndexingTask repositoryTask ) {
+ IndexingTask indexingTask = new IndexingTask( );
+ indexingTask.setFullRepository( repositoryTask.isFullScan());
+ indexingTask.setUpdateOnly( repositoryTask.isUpdateOnly() );
+ indexingTask.setResource( repositoryTask.getResource() );
+ indexingTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTimeMs() );
+ indexingTask.setRepositoryId( repositoryTask.getRepositoryId() );
+ 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( );
+ }
+
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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.
+ */
+
+/*
+ * 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;
+import java.util.TreeMap;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@XmlRootElement(name="ldapConfiguration")
+@Schema(name="LdapConfiguration", description = "LDAP configuration attributes")
+public class LdapConfiguration implements Serializable
+{
+ private static final long serialVersionUID = -4736767846016398583L;
+
+ private String hostName = "";
+ private int port = 389;
+ private String baseDn = "";
+ private String groupsBaseDn = "";
+ private String bindDn = "";
+ private String bindPassword = "";
+ private String authenticationMethod = "none";
+ private String contextFactory;
+ private boolean sslEnabled = false;
+ private boolean bindAuthenticatorEnabled = true;
+ private boolean useRoleNameAsGroup = false;
+ private Map<String, String> properties = new TreeMap<>();
+ private boolean writable = false;
+ private List<String> availableContextFactories;
+
+ public LdapConfiguration( )
+ {
+ }
+
+ public static LdapConfiguration of( org.apache.archiva.admin.model.beans.LdapConfiguration ldapConfiguration ) {
+ LdapConfiguration newCfg = new LdapConfiguration( );
+ newCfg.setAuthenticationMethod( ldapConfiguration.getAuthenticationMethod( ) );
+ newCfg.setBaseDn( ldapConfiguration.getBaseDn( ) );
+ newCfg.setGroupsBaseDn( ldapConfiguration.getBaseGroupsDn() );
+ newCfg.setBindDn( ldapConfiguration.getBindDn() );
+ newCfg.setBindPassword( ldapConfiguration.getPassword() );
+ newCfg.setBindAuthenticatorEnabled( ldapConfiguration.isBindAuthenticatorEnabled() );
+ newCfg.setHostName( ldapConfiguration.getHostName( ) );
+ newCfg.setSslEnabled( ldapConfiguration.isSsl() );
+ newCfg.setContextFactory( ldapConfiguration.getContextFactory() );
+ if (ldapConfiguration.getPort()<=0) {
+ newCfg.setPort( newCfg.isSslEnabled() ? 636 : 389 );
+ } else
+ {
+ newCfg.setPort( ldapConfiguration.getPort( ) );
+ }
+ newCfg.setProperties( ldapConfiguration.getExtraProperties( ) );
+ newCfg.setWritable( ldapConfiguration.isWritable() );
+ return newCfg;
+ }
+
+ @Schema(name="host_name", description = "The hostname to use to connect to the LDAP server")
+ public String getHostName( )
+ {
+ return hostName;
+ }
+
+ public void setHostName( String hostName )
+ {
+ this.hostName = hostName==null?"":hostName;
+ }
+
+ @Schema(description = "The port to use to connect to the LDAP server")
+ public int getPort( )
+ {
+ return port;
+ }
+
+ public void setPort( int port )
+ {
+ this.port = port;
+ }
+
+ @Schema(name="context_factory",description = "The class name of the LDAP context factory")
+ public String getContextFactory( )
+ {
+ return contextFactory;
+ }
+
+ public void setContextFactory( String contextFactory )
+ {
+ this.contextFactory = contextFactory;
+ }
+
+
+ @Schema(name="ssl_enabled", description = "True, if SSL/TLS should be used for connecting the LDAP server")
+ public boolean isSslEnabled( )
+ {
+ return sslEnabled;
+ }
+
+ public void setSslEnabled( boolean sslEnabled )
+ {
+ this.sslEnabled = sslEnabled;
+ }
+
+ @Schema(name="base_dn", description = "The BASE DN used for the LDAP server")
+ public String getBaseDn( )
+ {
+ return baseDn;
+ }
+
+ public void setBaseDn( String baseDn )
+ {
+ this.baseDn = baseDn == null ? "" : baseDn;
+ }
+
+ @Schema(name="bind_dn", description = "The distinguished name of the bind user which is used to bind to the LDAP server")
+ public String getBindDn( )
+ {
+ return bindDn;
+ }
+
+ public void setBindDn( String bindDn )
+ {
+ this.bindDn = bindDn == null ? "" : bindDn;
+ }
+
+ @Schema(name="bind_password", description = "The password used to bind to the ldap server")
+ public String getBindPassword( )
+ {
+ return bindPassword;
+ }
+
+ public void setBindPassword( String bindPassword )
+ {
+ this.bindPassword = bindPassword==null?"":bindPassword;
+ }
+
+ @Schema(name="groups_base_dn", description = "The distinguished name of the base to use for searching group.")
+ public String getGroupsBaseDn( )
+ {
+ return groupsBaseDn;
+ }
+
+ public void setGroupsBaseDn( String groupsBaseDn )
+ {
+ this.groupsBaseDn = groupsBaseDn==null?"":groupsBaseDn;
+ }
+
+ @Schema(name="authentication_method", description = "The authentication method used to bind to the LDAP server (PLAINTEXT, SASL, ...)")
+ public String getAuthenticationMethod( )
+ {
+ return authenticationMethod;
+ }
+
+ public void setAuthenticationMethod( String authenticationMethod )
+ {
+ this.authenticationMethod = authenticationMethod==null?"":authenticationMethod;
+ }
+
+ @Schema(name="bind_authenticator_enabled", description = "True, if the LDAP bind authentication is used for logging in to Archiva")
+ public boolean isBindAuthenticatorEnabled( )
+ {
+ return bindAuthenticatorEnabled;
+ }
+
+ public void setBindAuthenticatorEnabled( boolean bindAuthenticatorEnabled )
+ {
+ this.bindAuthenticatorEnabled = bindAuthenticatorEnabled;
+ }
+
+ @Schema(name="user_role_name_as_group", description = "True, if the archiva role name is also the LDAP group name")
+ public boolean isUseRoleNameAsGroup( )
+ {
+ return useRoleNameAsGroup;
+ }
+
+ public void setUseRoleNameAsGroup( boolean useRoleNameAsGroup )
+ {
+ this.useRoleNameAsGroup = useRoleNameAsGroup;
+ }
+
+ @Schema(description = "LDAP ConnectionFactory environment properties")
+ public Map<String, String> getProperties( )
+ {
+ return properties;
+ }
+
+ public void setProperties( Map<String, String> 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")
+ public boolean isWritable( )
+ {
+ return writable;
+ }
+
+ public void setWritable( boolean writable )
+ {
+ this.writable = writable;
+ }
+
+ @Schema(name="available_context_factories", description = "The LDAP context factories that are known and available")
+ public List<String> getAvailableContextFactories( )
+ {
+ return availableContextFactories;
+ }
+
+ public void setAvailableContextFactories( List<String> availableContextFactories )
+ {
+ this.availableContextFactories = new ArrayList<>( availableContextFactories );
+ }
+
+ public void addAvailableContextFactory(String contextFactory) {
+ if (!this.availableContextFactories.contains( contextFactory ) ) {
+ this.availableContextFactories.add( contextFactory );
+ }
+ }
+
+
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ LdapConfiguration that = (LdapConfiguration) o;
+
+ if ( port != that.port ) return false;
+ if ( sslEnabled != that.sslEnabled ) return false;
+ if ( bindAuthenticatorEnabled != that.bindAuthenticatorEnabled ) return false;
+ if ( useRoleNameAsGroup != that.useRoleNameAsGroup ) return false;
+ if ( writable != that.writable ) return false;
+ if ( !Objects.equals( hostName, that.hostName ) ) return false;
+ if ( !Objects.equals( baseDn, that.baseDn ) ) return false;
+ if ( !Objects.equals( bindDn, that.bindDn ) ) return false;
+ if ( !Objects.equals( groupsBaseDn, that.groupsBaseDn ) )
+ return false;
+ if ( !Objects.equals( bindPassword, that.bindPassword ) ) return false;
+ if ( !Objects.equals( authenticationMethod, that.authenticationMethod ) )
+ return false;
+ return properties.equals( that.properties );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = hostName != null ? hostName.hashCode( ) : 0;
+ result = 31 * result + port;
+ result = 31 * result + ( sslEnabled ? 1 : 0 );
+ result = 31 * result + ( baseDn != null ? baseDn.hashCode( ) : 0 );
+ result = 31 * result + ( bindDn != null ? bindDn.hashCode( ) : 0 );
+ result = 31 * result + ( groupsBaseDn != null ? groupsBaseDn.hashCode( ) : 0 );
+ result = 31 * result + ( bindPassword != null ? bindPassword.hashCode( ) : 0 );
+ result = 31 * result + ( authenticationMethod != null ? authenticationMethod.hashCode( ) : 0 );
+ result = 31 * result + ( bindAuthenticatorEnabled ? 1 : 0 );
+ result = 31 * result + ( useRoleNameAsGroup ? 1 : 0 );
+ result = 31 * result + properties.hashCode( );
+ result = 31 * result + ( writable ? 1 : 0 );
+ return result;
+ }
+
+ @SuppressWarnings( "StringBufferReplaceableByString" )
+ @Override
+ public String toString( )
+ {
+ final StringBuilder sb = new StringBuilder( "LdapConfiguration{" );
+ sb.append( "host_name='" ).append( hostName ).append( '\'' );
+ sb.append( ", port=" ).append( port );
+ sb.append( ", ssl_enabled=" ).append( sslEnabled );
+ sb.append( ", base_dn='" ).append( baseDn ).append( '\'' );
+ sb.append( ", groups_base_dn='" ).append( groupsBaseDn ).append( '\'' );
+ sb.append( ", bind_dn='" ).append( bindDn ).append( '\'' );
+ sb.append( ", bind_password='" ).append( bindPassword ).append( '\'' );
+ sb.append( ", authentication_method='" ).append( authenticationMethod ).append( '\'' );
+ sb.append( ", bind_authenticator_enabled=" ).append( bindAuthenticatorEnabled );
+ sb.append( ", use_role_name_as_group=" ).append( useRoleNameAsGroup );
+ sb.append( ", properties=" ).append( properties );
+ sb.append( ", writable=" ).append( writable );
+ sb.append( '}' );
+ return sb.toString( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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.
+ */
+
+/*
+ * 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.RepositoryType;
+import org.apache.archiva.repository.features.ArtifactCleanupFeature;
+import org.apache.archiva.repository.features.IndexCreationFeature;
+import org.apache.archiva.repository.features.StagingRepositoryFeature;
+
+import java.time.Period;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="MavenManagedRepository",description = "A managed repository stores artifacts locally")
+public class MavenManagedRepository extends Repository
+{
+ private static final long serialVersionUID = -6853748886201905029L;
+
+ boolean blocksRedeployments;
+ List<String> releaseSchemes = new ArrayList<>( );
+ boolean deleteSnapshotsOfRelease = false;
+ private Period retentionPeriod;
+ private int retentionCount;
+ private String indexPath;
+ private String packedIndexPath;
+ private boolean skipPackedIndexCreation;
+ private boolean hasStagingRepository;
+ private String stagingRepository;
+
+
+ public MavenManagedRepository( )
+ {
+ super.setCharacteristic( Repository.CHARACTERISTIC_MANAGED );
+ super.setType( RepositoryType.MAVEN.name( ) );
+ }
+
+ protected static void update(MavenManagedRepository repo, ManagedRepository beanRepo) {
+ repo.setDescription( beanRepo.getDescription() );
+ repo.setId( beanRepo.getId() );
+ repo.setIndex( true );
+ repo.setLayout( beanRepo.getLayout() );
+ repo.setBlocksRedeployments( beanRepo.blocksRedeployments() );
+ repo.setReleaseSchemes( beanRepo.getActiveReleaseSchemes().stream().map( Objects::toString).collect( Collectors.toList()) );
+ repo.setLocation( beanRepo.getLocation().toString() );
+ repo.setName( beanRepo.getName());
+ repo.setScanned( beanRepo.isScanned() );
+ repo.setSchedulingDefinition( beanRepo.getSchedulingDefinition() );
+ ArtifactCleanupFeature artifactCleanupFeature = beanRepo.getFeature( ArtifactCleanupFeature.class ).get( );
+ repo.setDeleteSnapshotsOfRelease( artifactCleanupFeature.isDeleteReleasedSnapshots());
+ repo.setRetentionCount( artifactCleanupFeature.getRetentionCount());
+ repo.setRetentionPeriod( artifactCleanupFeature.getRetentionPeriod() );
+ IndexCreationFeature icf = beanRepo.getFeature( IndexCreationFeature.class ).get( );
+ repo.setIndex( icf.hasIndex( ) );
+ repo.setIndexPath( icf.getIndexPath( ).getPath( ) );
+ repo.setPackedIndexPath( icf.getPackedIndexPath( ).getPath( ) );
+ repo.setSkipPackedIndexCreation( icf.isSkipPackedIndexCreation() );
+ StagingRepositoryFeature srf = beanRepo.getFeature( StagingRepositoryFeature.class ).get( );
+ repo.setHasStagingRepository( srf.isStageRepoNeeded( ) );
+ repo.setStagingRepository( srf.getStagingRepository()!=null?srf.getStagingRepository().getId():"" );
+ }
+
+ public static MavenManagedRepository of( ManagedRepository beanRepo ) {
+ MavenManagedRepository repo = new MavenManagedRepository( );
+ update( repo, beanRepo );
+ return repo;
+ }
+
+ @Schema(name="blocks_redeployments",description = "True, if redeployments to this repository are not allowed")
+ public boolean isBlocksRedeployments( )
+ {
+ return blocksRedeployments;
+ }
+
+ public void setBlocksRedeployments( boolean blocksRedeployments )
+ {
+ this.blocksRedeployments = blocksRedeployments;
+ }
+
+ @Schema(name="release_schemes", description = "The release schemes this repository is used for (e.g. RELEASE, SNAPSHOT)")
+ public List<String> getReleaseSchemes( )
+ {
+ return releaseSchemes;
+ }
+
+ public void setReleaseSchemes( List<String> releaseSchemes )
+ {
+ this.releaseSchemes = new ArrayList<>( releaseSchemes );
+ }
+
+ public void addReleaseScheme(String scheme) {
+ if (!this.releaseSchemes.contains( scheme ))
+ {
+ this.releaseSchemes.add( scheme );
+ }
+ }
+
+ @Schema(name="delete_snaphots_of_release", description = "True, if snapshots are deleted, after a version is released")
+ public boolean isDeleteSnapshotsOfRelease( )
+ {
+ return deleteSnapshotsOfRelease;
+ }
+
+ public void setDeleteSnapshotsOfRelease( boolean deleteSnapshotsOfRelease )
+ {
+ this.deleteSnapshotsOfRelease = deleteSnapshotsOfRelease;
+ }
+
+ @Schema(name="retention_period", description = "The period after which snapshots are deleted.")
+ public Period getRetentionPeriod( )
+ {
+ return retentionPeriod;
+ }
+
+ public void setRetentionPeriod( Period retentionPeriod )
+ {
+ this.retentionPeriod = retentionPeriod;
+ }
+
+ @Schema(name="retention_count", description = "Number of snapshot artifacts to keep.")
+ public int getRetentionCount( )
+ {
+ return retentionCount;
+ }
+
+ public void setRetentionCount( int retentionCount )
+ {
+ this.retentionCount = retentionCount;
+ }
+
+ @Schema( name = "index_path", description = "Path to the directory that contains the index, 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 directory that contains the packed index, relative to the repository base directory" )
+ public String getPackedIndexPath( )
+ {
+ return packedIndexPath;
+ }
+
+ public void setPackedIndexPath( String packedIndexPath )
+ {
+ this.packedIndexPath = packedIndexPath;
+ }
+
+ @Schema(name="skip_packed_index_creation", description = "True, if packed index is not created during index update")
+ public boolean isSkipPackedIndexCreation( )
+ {
+ return skipPackedIndexCreation;
+ }
+
+ public void setSkipPackedIndexCreation( boolean skipPackedIndexCreation )
+ {
+ this.skipPackedIndexCreation = skipPackedIndexCreation;
+ }
+
+ @Schema(name="has_staging_repository", description = "True, if this repository has a staging repository assigned")
+ public boolean isHasStagingRepository( )
+ {
+ return hasStagingRepository;
+ }
+
+ public void setHasStagingRepository( boolean hasStagingRepository )
+ {
+ this.hasStagingRepository = hasStagingRepository;
+ }
+
+ @Schema(name="staging_repository", description = "The id of the assigned staging repository")
+ public String getStagingRepository( )
+ {
+ return stagingRepository;
+ }
+
+ public void setStagingRepository( String stagingRepository )
+ {
+ this.stagingRepository = stagingRepository;
+ }
+
+ @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( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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 org.apache.archiva.repository.ManagedRepository;
+
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class MavenManagedRepositoryUpdate extends MavenManagedRepository implements Serializable
+{
+ private static final long serialVersionUID = -9181643343284109862L;
+ private boolean resetStats = false;
+
+ public static MavenManagedRepositoryUpdate of( ManagedRepository repository ) {
+ MavenManagedRepositoryUpdate repo = new MavenManagedRepositoryUpdate( );
+ update( repo, repository );
+ return repo;
+ }
+
+ public boolean isResetStats( )
+ {
+ return resetStats;
+ }
+
+ public void setResetStats( boolean resetStats )
+ {
+ this.resetStats = resetStats;
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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 io.swagger.v3.oas.annotations.media.Schema;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Schema(name="MavenRemoteRepository",description = "A remote repository definition is used to pull artifacts from other repositories")
+public class MavenRemoteRepository extends Repository
+{
+ private static final long serialVersionUID = 5625043398766480265L;
+ String loginUser;
+ String loginPassword;
+ String checkPath;
+ Map<String,String> extraParameters = new TreeMap<>( );
+ Map<String,String> requestHeader = new TreeMap<>( );
+ long timeoutMs;
+
+ @Schema(name="login_user",description = "Username for login to the remote repository")
+ public String getLoginUser( )
+ {
+ return loginUser;
+ }
+
+ public void setLoginUser( String loginUser )
+ {
+ this.loginUser = loginUser;
+ }
+
+ @Schema(name="login_password",description = "Password for connecting to the remote repository")
+ public String getLoginPassword( )
+ {
+ return loginPassword;
+ }
+
+ public void setLoginPassword( String loginPassword )
+ {
+ this.loginPassword = loginPassword;
+ }
+
+ @Schema(name="check_path",description = "Path relative to the repository URL that is used to check of availability of the remote repository.")
+ public String getCheckPath( )
+ {
+ return checkPath;
+ }
+
+ public void setCheckPath( String checkPath )
+ {
+ this.checkPath = checkPath;
+ }
+
+ @Schema(name="extra_parameters", description = "Key-Value map with extra parameters sent to the remote repository")
+ public Map<String, String> getExtraParameters( )
+ {
+ return extraParameters;
+ }
+
+ public void setExtraParameters( Map<String, String> extraParameters )
+ {
+ this.extraParameters = new TreeMap<>( extraParameters );
+ }
+
+ public void addExtraParameter(String key, String value) {
+ this.extraParameters.put( key, value );
+ }
+
+ @Schema(name="request_header",description = "Key-Value map with request headers that are sent to the remote repository")
+ public Map<String, String> getRequestHeader( )
+ {
+ return requestHeader;
+ }
+
+ public void setRequestHeader( Map<String, String> requestHeader )
+ {
+ this.requestHeader = new TreeMap<>( requestHeader );
+ }
+
+ public void addRequestHeader(String headerName, String headerValue) {
+ this.requestHeader.put( headerName, headerValue );
+ }
+
+ @Schema(name="timeout_ms", description = "The time in milliseconds after that a request to the remote repository is aborted")
+ public long getTimeoutMs( )
+ {
+ return timeoutMs;
+ }
+
+ public void setTimeoutMs( long timeoutMs )
+ {
+ this.timeoutMs = timeoutMs;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+ if ( !super.equals( o ) ) return false;
+
+ MavenRemoteRepository that = (MavenRemoteRepository) o;
+
+ if ( timeoutMs != that.timeoutMs ) return false;
+ if ( loginUser != null ? !loginUser.equals( that.loginUser ) : that.loginUser != null ) return false;
+ if ( loginPassword != null ? !loginPassword.equals( that.loginPassword ) : that.loginPassword != null )
+ return false;
+ if ( checkPath != null ? !checkPath.equals( that.checkPath ) : that.checkPath != null ) return false;
+ if ( extraParameters != null ? !extraParameters.equals( that.extraParameters ) : that.extraParameters != null )
+ return false;
+ return requestHeader != null ? requestHeader.equals( that.requestHeader ) : that.requestHeader == null;
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = super.hashCode( );
+ result = 31 * result + ( loginUser != null ? loginUser.hashCode( ) : 0 );
+ result = 31 * result + ( loginPassword != null ? loginPassword.hashCode( ) : 0 );
+ result = 31 * result + ( checkPath != null ? checkPath.hashCode( ) : 0 );
+ result = 31 * result + ( extraParameters != null ? extraParameters.hashCode( ) : 0 );
+ result = 31 * result + ( requestHeader != null ? requestHeader.hashCode( ) : 0 );
+ result = 31 * result + (int) ( timeoutMs ^ ( timeoutMs >>> 32 ) );
+ return result;
+ }
+
+ @Override
+ public String toString( )
+ {
+ final StringBuilder sb = new StringBuilder( "RemoteRepository{" );
+ sb.append( "loginUser='" ).append( loginUser ).append( '\'' );
+ sb.append( ", loginPassword='" ).append( loginPassword ).append( '\'' );
+ sb.append( ", checkPath='" ).append( checkPath ).append( '\'' );
+ sb.append( ", extraParameters=" ).append( extraParameters );
+ sb.append( ", requestHeader=" ).append( requestHeader );
+ sb.append( ", timeOut=" ).append( timeoutMs );
+ sb.append( ", id='" ).append( id ).append( '\'' );
+ sb.append( ", name='" ).append( name ).append( '\'' );
+ sb.append( ", description='" ).append( description ).append( '\'' );
+ sb.append( ", type='" ).append( type ).append( '\'' );
+ sb.append( ", location='" ).append( location ).append( '\'' );
+ sb.append( ", scanned=" ).append( scanned );
+ sb.append( ", schedulingDefinition='" ).append( schedulingDefinition ).append( '\'' );
+ sb.append( ", index=" ).append( index );
+ sb.append( ", layout='" ).append( layout ).append( '\'' );
+ sb.append( '}' );
+ return sb.toString( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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.
+ */
+
+/*
+ * 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.Objects;
+
+import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_INDEX_PATH;
+
+/**
+ * Index merge configuration.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@XmlRootElement(name="mergeConfiguration")
+@Schema(name="MergeConfiguration", description = "Configuration settings for index merge of remote repositories.")
+public class MergeConfiguration implements Serializable
+{
+ private static final long serialVersionUID = -3629274059574459133L;
+
+ private String mergedIndexPath = DEFAULT_INDEX_PATH;
+ private int mergedIndexTtlMinutes = 30;
+ private String indexMergeSchedule = "";
+
+ @Schema(name="merged_index_path", description = "The path where the merged index is stored. The path is relative to the repository directory of the group.")
+ public String getMergedIndexPath( )
+ {
+ return mergedIndexPath;
+ }
+
+ public void setMergedIndexPath( String mergedIndexPath )
+ {
+ this.mergedIndexPath = mergedIndexPath;
+ }
+
+ @Schema(name="merged_index_ttl_minutes", description = "The Time to Life of the merged index in minutes.")
+ public int getMergedIndexTtlMinutes( )
+ {
+ return mergedIndexTtlMinutes;
+ }
+
+ public void setMergedIndexTtlMinutes( int mergedIndexTtlMinutes )
+ {
+ this.mergedIndexTtlMinutes = mergedIndexTtlMinutes;
+ }
+
+ @Schema(name="index_merge_schedule", description = "Cron expression that defines the times/intervals for index merging.")
+ public String getIndexMergeSchedule( )
+ {
+ return indexMergeSchedule;
+ }
+
+ public void setIndexMergeSchedule( String indexMergeSchedule )
+ {
+ this.indexMergeSchedule = indexMergeSchedule;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ MergeConfiguration that = (MergeConfiguration) o;
+
+ if ( mergedIndexTtlMinutes != that.mergedIndexTtlMinutes ) return false;
+ if ( !Objects.equals( mergedIndexPath, that.mergedIndexPath ) )
+ return false;
+ return Objects.equals( indexMergeSchedule, that.indexMergeSchedule );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = mergedIndexPath != null ? mergedIndexPath.hashCode( ) : 0;
+ result = 31 * result + mergedIndexTtlMinutes;
+ result = 31 * result + ( indexMergeSchedule != null ? indexMergeSchedule.hashCode( ) : 0 );
+ return result;
+ }
+
+ @SuppressWarnings( "StringBufferReplaceableByString" )
+ @Override
+ public String toString( )
+ {
+ final StringBuilder sb = new StringBuilder( "MergeConfiguration{" );
+ sb.append( "mergedIndexPath='" ).append( mergedIndexPath ).append( '\'' );
+ sb.append( ", mergedIndexTtlMinutes=" ).append( mergedIndexTtlMinutes );
+ sb.append( ", indexMergeSchedule='" ).append( indexMergeSchedule ).append( '\'' );
+ sb.append( '}' );
+ return sb.toString( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.repository.ManagedRepository;
+import org.apache.archiva.repository.RemoteRepository;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Schema(description = "Repository data")
+public class Repository implements Serializable
+{
+ private static final long serialVersionUID = -4741025877287175182L;
+
+ public static final String CHARACTERISTIC_MANAGED = "managed";
+ public static final String CHARACTERISTIC_REMOTE = "remote";
+ public static final String CHARACTERISTIC_UNKNOWN = "unknown";
+
+ protected String id;
+ protected String name;
+ protected String description;
+ protected String type;
+ protected String characteristic;
+ protected String location;
+ protected boolean scanned;
+ protected String schedulingDefinition;
+ protected boolean index;
+ protected String layout;
+
+ public Repository( )
+ {
+ }
+
+ public static Repository of( org.apache.archiva.repository.Repository repository ) {
+ Repository newRepo = new Repository( );
+ newRepo.setId( repository.getId() );
+ newRepo.setName( repository.getName( ) );
+ newRepo.setDescription( repository.getDescription( ) );
+ newRepo.setLocation( repository.getLocation().toASCIIString() );
+ newRepo.setIndex( repository.hasIndex() );
+ newRepo.setLayout( repository.getLayout() );
+ newRepo.setType( repository.getType().name() );
+ newRepo.setScanned( repository.isScanned() );
+ newRepo.setSchedulingDefinition( repository.getSchedulingDefinition() );
+ if (repository instanceof RemoteRepository ) {
+ newRepo.setCharacteristic( CHARACTERISTIC_REMOTE );
+ } else if (repository instanceof ManagedRepository ) {
+ newRepo.setCharacteristic( CHARACTERISTIC_MANAGED );
+ } else {
+ newRepo.setCharacteristic( CHARACTERISTIC_UNKNOWN );
+ }
+ return newRepo;
+ }
+
+ public static Repository of( org.apache.archiva.repository.Repository repository, Locale locale ) {
+ Locale myLocale;
+ if (locale==null) {
+ myLocale = Locale.getDefault( );
+ } else {
+ myLocale = locale;
+ }
+ String repoName = repository.getName( myLocale );
+ if (repoName==null) {
+ repoName = repository.getName( );
+ }
+ String description = repository.getDescription( myLocale );
+ if (description==null) {
+ description = repository.getDescription( );
+ }
+ Repository newRepo = new Repository( );
+ newRepo.setId( repository.getId() );
+ newRepo.setName( repoName );
+ newRepo.setDescription( description );
+ 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( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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.
+ */
+
+/*
+ * 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.features.IndexCreationFeature;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@XmlRootElement(name="repositoryGroup")
+@Schema(name="RepositoryGroup", description = "Information about a repository group, which combines multiple repositories as one virtual repository.")
+public class RepositoryGroup implements Serializable
+{
+ private static final long serialVersionUID = -7319687481737616081L;
+ private String id;
+ private String name;
+ private List<String> repositories = new ArrayList<>( );
+ private String location;
+ MergeConfiguration mergeConfiguration;
+
+ public RepositoryGroup( )
+ {
+ }
+
+ public RepositoryGroup(String id) {
+ this.id = id;
+ }
+
+ public static RepositoryGroup of( org.apache.archiva.repository.RepositoryGroup modelObj ) {
+ RepositoryGroup result = new RepositoryGroup( );
+ MergeConfiguration mergeConfig = new MergeConfiguration( );
+ result.setMergeConfiguration( mergeConfig );
+ result.setId( modelObj.getId() );
+ result.setName( modelObj.getName() );
+ result.setLocation( modelObj.getLocation().toString() );
+ result.setRepositories( modelObj.getRepositories().stream().map( Repository::getId ).collect( Collectors.toList()) );
+ if (modelObj.supportsFeature( IndexCreationFeature.class )) {
+ IndexCreationFeature icf = modelObj.getFeature( IndexCreationFeature.class ).get();
+ mergeConfig.setMergedIndexPath( icf.getIndexPath( ).toString() );
+ mergeConfig.setMergedIndexTtlMinutes( modelObj.getMergedIndexTTL( ) );
+ mergeConfig.setIndexMergeSchedule( modelObj.getSchedulingDefinition() );
+ }
+ return result;
+ }
+
+ @Schema(description = "The unique id of the repository group.")
+ public String getId( )
+ {
+ return id;
+ }
+
+ public void setId( String id )
+ {
+ this.id = id;
+ }
+
+ @Schema(description = "The list of ids of repositories which are member of the repository group.")
+ public List<String> getRepositories( )
+ {
+ return repositories;
+ }
+
+ public void setRepositories( List<String> repositories )
+ {
+ this.repositories = new ArrayList<>( repositories );
+ }
+
+ public void addRepository(String repositoryId) {
+ if (!this.repositories.contains( repositoryId )) {
+ this.repositories.add( repositoryId );
+ }
+ }
+
+ @Schema(name="merge_configuration",description = "The configuration for index merge.")
+ public MergeConfiguration getMergeConfiguration( )
+ {
+ return mergeConfiguration;
+ }
+
+ public void setMergeConfiguration( MergeConfiguration mergeConfiguration )
+ {
+ this.mergeConfiguration = mergeConfiguration;
+ }
+
+ @Schema(description = "The storage location of the repository. The merged index is stored relative to this location.")
+ public String getLocation( )
+ {
+ return location;
+ }
+
+ public void setLocation( String location )
+ {
+ this.location = location;
+ }
+
+ @Schema(description = "The name of the repository group")
+ public String getName( )
+ {
+ return name;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ RepositoryGroup that = (RepositoryGroup) o;
+
+ return id.equals( that.id );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ return id.hashCode( );
+ }
+
+ @Override
+ public String toString( )
+ {
+ final StringBuilder sb = new StringBuilder( "RepositoryGroup{" );
+ sb.append( "id='" ).append( id ).append( '\'' );
+ sb.append( ", name='" ).append( name ).append( '\'' );
+ sb.append( ", repositories=" ).append( repositories );
+ sb.append( ", location='" ).append( location ).append( '\'' );
+ sb.append( ", mergeConfiguration=" ).append( mergeConfiguration );
+ sb.append( '}' );
+ return sb.toString( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.repository.scanner.RepositoryScanStatistics;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.time.Duration;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@XmlRootElement(name="repositoryStatistics")
+@Schema(name="RepositoryStatistics", description = "Statistics data")
+public class RepositoryStatistics implements Serializable
+{
+ private static final long serialVersionUID = 7943367882738452531L;
+
+ private OffsetDateTime scanEndTime;
+ private OffsetDateTime scanStartTime;
+ private long scanDurationMs;
+ private long totalArtifactCount;
+ private long totalArtifactFileSize;
+ private long totalFileCount;
+ private long totalGroupCount;
+ private long totalProjectCount;
+ private long newFileCount;
+ private Map<String, Long> totalCountForType = new TreeMap<>( );
+ private Map<String, Long> customValues = new TreeMap<>( );
+
+ public RepositoryStatistics( )
+ {
+ }
+
+ public static RepositoryStatistics of( org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics modelStats ) {
+ RepositoryStatistics newStats = new RepositoryStatistics( );
+ newStats.setScanStartTime( modelStats.getScanStartTime().toInstant().atOffset( ZoneOffset.UTC ) );
+ newStats.setScanEndTime( modelStats.getScanEndTime( ).toInstant( ).atOffset( ZoneOffset.UTC ) );
+ newStats.setNewFileCount( modelStats.getNewFileCount() );
+ newStats.setScanDurationMs( Duration.between( newStats.scanStartTime, newStats.scanEndTime ).toMillis() );
+ newStats.setTotalArtifactCount( modelStats.getTotalArtifactCount() );
+ newStats.setTotalArtifactFileSize( modelStats.getTotalArtifactFileSize() );
+ newStats.setTotalCountForType( modelStats.getTotalCountForType() );
+ newStats.setTotalFileCount( modelStats.getTotalFileCount() );
+ newStats.setTotalGroupCount( modelStats.getTotalGroupCount() );
+ newStats.setTotalProjectCount( modelStats.getTotalProjectCount() );
+ for (String key : modelStats.getAvailableCustomValues()) {
+ newStats.addCustomValue( key, modelStats.getCustomValue( key ) );
+ }
+ return newStats;
+ }
+
+ public static RepositoryStatistics of( RepositoryScanStatistics scanStatistics ) {
+ RepositoryStatistics newStats = new RepositoryStatistics( );
+ newStats.setScanStartTime( scanStatistics.getWhenGathered().toInstant().atOffset( ZoneOffset.UTC ) );
+ newStats.setScanEndTime( OffsetDateTime.now(ZoneOffset.UTC) );
+ newStats.setNewFileCount( scanStatistics.getNewFileCount() );
+ newStats.setScanDurationMs( Duration.between( newStats.scanStartTime, newStats.scanEndTime ).toMillis() );
+ newStats.setTotalArtifactCount( scanStatistics.getTotalFileCount() );
+ newStats.setTotalArtifactFileSize( scanStatistics.getTotalSize() );
+ newStats.setTotalFileCount( scanStatistics.getTotalFileCount() );
+ newStats.setTotalGroupCount( 0 );
+ newStats.setTotalProjectCount( 0 );
+ return newStats;
+ }
+
+ @Schema(name="scan_end_time", description = "Date and time when the last scan finished")
+ public OffsetDateTime getScanEndTime( )
+ {
+ return scanEndTime;
+ }
+
+ public void setScanEndTime( OffsetDateTime scanEndTime )
+ {
+ this.scanEndTime = scanEndTime;
+ }
+
+ @Schema( name = "scan_start_time", description = "Date and time when the last scan started" )
+ public OffsetDateTime getScanStartTime( )
+ {
+ return scanStartTime;
+ }
+
+ public void setScanStartTime( OffsetDateTime scanStartTime )
+ {
+ this.scanStartTime = scanStartTime;
+ }
+
+ @Schema(name="total_artifact_count", description = "The number of artifacts scanned")
+ public long getTotalArtifactCount( )
+ {
+ return totalArtifactCount;
+ }
+
+ public void setTotalArtifactCount( long totalArtifactCount )
+ {
+ this.totalArtifactCount = totalArtifactCount;
+ }
+
+ @Schema(name="total_artifact_file_size", description = "The cumulative size of all files scanned")
+ public long getTotalArtifactFileSize( )
+ {
+ return totalArtifactFileSize;
+ }
+
+ public void setTotalArtifactFileSize( long totalArtifactFileSize )
+ {
+ this.totalArtifactFileSize = totalArtifactFileSize;
+ }
+
+ @Schema(name="total_file_count", description = "The total number of files scanned")
+ public long getTotalFileCount( )
+ {
+ return totalFileCount;
+ }
+
+ public void setTotalFileCount( long totalFileCount )
+ {
+ this.totalFileCount = totalFileCount;
+ }
+
+ @Schema(name="total_group_count", description = "The number of groups scanned")
+ public long getTotalGroupCount( )
+ {
+ return totalGroupCount;
+ }
+
+ public void setTotalGroupCount( long totalGroupCount )
+ {
+ this.totalGroupCount = totalGroupCount;
+ }
+
+ @Schema(name="total_project_count", description = "The number of projects scanned")
+ public long getTotalProjectCount( )
+ {
+ return totalProjectCount;
+ }
+
+ public void setTotalProjectCount( long totalProjectCount )
+ {
+ this.totalProjectCount = totalProjectCount;
+ }
+
+ @Schema(name="new_file_count", description = "Number of files registered as new")
+ public long getNewFileCount( )
+ {
+ return newFileCount;
+ }
+
+ public void setNewFileCount( long newFileCount )
+ {
+ this.newFileCount = newFileCount;
+ }
+
+ @Schema(name="scan_duration_ms", description = "The duration of the last scan in ms")
+ public long getScanDurationMs( )
+ {
+ return scanDurationMs;
+ }
+
+ public void setScanDurationMs( long scanDurationMs )
+ {
+ this.scanDurationMs = scanDurationMs;
+ }
+
+ @Schema(name="total_count_for_type", description = "File counts partitioned by file types")
+ public Map<String, Long> getTotalCountForType( )
+ {
+ return totalCountForType;
+ }
+
+ public void setTotalCountForType( Map<String, Long> totalCountForType )
+ {
+ this.totalCountForType = new TreeMap<>( totalCountForType );
+ }
+
+ public void addTotalCountForType( String type, Long value )
+ {
+ this.totalCountForType.put( type, value );
+ }
+
+ @Schema(name="custom_values", description = "Custom statistic values")
+ public Map<String, Long> getCustomValues( )
+ {
+ return customValues;
+ }
+
+ public void setCustomValues( Map<String, Long> customValues )
+ {
+ this.customValues = new TreeMap<>( customValues );
+ }
+
+ public void addCustomValue(String type, Long value) {
+ this.customValues.put( type, value );
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ RepositoryStatistics that = (RepositoryStatistics) o;
+
+ if ( scanDurationMs != that.scanDurationMs ) return false;
+ if ( totalArtifactCount != that.totalArtifactCount ) return false;
+ if ( totalArtifactFileSize != that.totalArtifactFileSize ) return false;
+ if ( totalFileCount != that.totalFileCount ) return false;
+ if ( totalGroupCount != that.totalGroupCount ) return false;
+ if ( totalProjectCount != that.totalProjectCount ) return false;
+ if ( newFileCount != that.newFileCount ) return false;
+ if ( scanEndTime != null ? !scanEndTime.equals( that.scanEndTime ) : that.scanEndTime != null ) return false;
+ if ( scanStartTime != null ? !scanStartTime.equals( that.scanStartTime ) : that.scanStartTime != null )
+ return false;
+ if ( !totalCountForType.equals( that.totalCountForType ) ) return false;
+ return customValues.equals( that.customValues );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = scanEndTime != null ? scanEndTime.hashCode( ) : 0;
+ result = 31 * result + ( scanStartTime != null ? scanStartTime.hashCode( ) : 0 );
+ result = 31 * result + (int) ( scanDurationMs ^ ( scanDurationMs >>> 32 ) );
+ result = 31 * result + (int) ( totalArtifactCount ^ ( totalArtifactCount >>> 32 ) );
+ result = 31 * result + (int) ( totalArtifactFileSize ^ ( totalArtifactFileSize >>> 32 ) );
+ result = 31 * result + (int) ( totalFileCount ^ ( totalFileCount >>> 32 ) );
+ result = 31 * result + (int) ( totalGroupCount ^ ( totalGroupCount >>> 32 ) );
+ result = 31 * result + (int) ( totalProjectCount ^ ( totalProjectCount >>> 32 ) );
+ result = 31 * result + (int) ( newFileCount ^ ( newFileCount >>> 32 ) );
+ result = 31 * result + totalCountForType.hashCode( );
+ result = 31 * result + customValues.hashCode( );
+ return result;
+ }
+
+ @Override
+ public String toString( )
+ {
+ final StringBuilder sb = new StringBuilder( "RepositoryStatistics{" );
+ sb.append( "scanEndTime=" ).append( scanEndTime );
+ sb.append( ", scanStartTime=" ).append( scanStartTime );
+ sb.append( ", scanDurationMs=" ).append( scanDurationMs );
+ sb.append( ", totalArtifactCount=" ).append( totalArtifactCount );
+ sb.append( ", totalArtifactFileSize=" ).append( totalArtifactFileSize );
+ sb.append( ", totalFileCount=" ).append( totalFileCount );
+ sb.append( ", totalGroupCount=" ).append( totalGroupCount );
+ sb.append( ", totalProjectCount=" ).append( totalProjectCount );
+ sb.append( ", newFileCount=" ).append( newFileCount );
+ sb.append( '}' );
+ return sb.toString( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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 io.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.admin.model.beans.MetadataScanTask;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="ScanStatus", description = "Status of repository scan tasks")
+public class ScanStatus implements Serializable
+{
+ private boolean scanRunning = false;
+ private int scanQueued = 0;
+ private boolean indexRunning = false;
+ private int indexQueued = 0;
+ private List<IndexingTask> indexingQueue = new ArrayList<>( );
+ private List<ScanTask> scanQueue = new ArrayList<>( );
+
+ public ScanStatus( )
+ {
+ }
+
+ public static ScanStatus of( org.apache.archiva.admin.model.beans.ScanStatus modelStatus ) {
+ ScanStatus status = new ScanStatus( );
+ status.setIndexRunning( modelStatus.isIndexScanRunning() );
+ status.setScanRunning( modelStatus.isMetadataScanRunning() );
+ List<org.apache.archiva.admin.model.beans.IndexingTask> indexQueue = modelStatus.getIndexingQueue( );
+ status.setIndexingQueue( indexQueue.stream().map(IndexingTask::of).collect( Collectors.toList()) );
+ status.setIndexQueued( indexQueue.size( ) > 0 ? indexQueue.size( ) - 1 : 0 );
+ List<MetadataScanTask> scanQueue = modelStatus.getScanQueue( );
+ status.setScanQueue( scanQueue.stream().map( ScanTask::of ).collect( Collectors.toList()) );
+ status.setScanQueued( scanQueue.size( ) > 0 ? scanQueue.size( ) - 1 : 0 );
+ return status;
+
+ }
+
+ @Schema( name = "scan_running", description = "True, if a scan is currently running" )
+ public boolean isScanRunning( )
+ {
+ return scanRunning;
+ }
+
+ public void setScanRunning( boolean scanRunning )
+ {
+ this.scanRunning = scanRunning;
+ }
+
+ @Schema(name ="scan_queued", description = "Number of scans in the task queue")
+ public int getScanQueued( )
+ {
+ return scanQueued;
+ }
+
+ public void setScanQueued( int scanQueued )
+ {
+ this.scanQueued = scanQueued;
+ }
+
+ @Schema(name="index_running", description = "True, if there is a index task currently running")
+ public boolean isIndexRunning( )
+ {
+ return indexRunning;
+ }
+
+ public void setIndexRunning( boolean indexRunning )
+ {
+ this.indexRunning = indexRunning;
+ }
+
+ @Schema(name="index_queued", description = "Number of queued index tasks")
+ public int getIndexQueued( )
+ {
+ return indexQueued;
+ }
+
+ public void setIndexQueued( int indexQueued )
+ {
+ this.indexQueued = indexQueued;
+ }
+
+ @Schema( name = "indexing_queue", description = "List of indexing tasks waiting for execution" )
+ public List<IndexingTask> getIndexingQueue( )
+ {
+ return indexingQueue;
+ }
+
+ public void setIndexingQueue( List<IndexingTask> indexingQueue )
+ {
+ this.indexingQueue = new ArrayList<>( indexingQueue );
+ }
+
+ @Schema(name="scan_queue", description = "List of scan tasks waiting for execution")
+ public List<ScanTask> getScanQueue( )
+ {
+ return scanQueue;
+ }
+
+ public void setScanQueue( List<ScanTask> scanQueue )
+ {
+ this.scanQueue = new ArrayList<>( scanQueue );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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 io.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.admin.model.beans.MetadataScanTask;
+
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="ScanTask", description = "Repository scan task information")
+public class ScanTask implements Serializable
+{
+ private static final long serialVersionUID = -681163357370848098L;
+ private String repositoryId="";
+ private boolean updateRelatedArtifacts;
+ private boolean fullRepository;
+ private boolean running = false;
+ private String resource = "";
+ private long maxExecutionTimeMs = 0;
+
+ public static ScanTask of( MetadataScanTask repositoryTask ) {
+ ScanTask scanTask = new ScanTask( );
+ scanTask.setFullRepository( repositoryTask.isFullScan());
+ scanTask.setUpdateRelatedArtifacts( repositoryTask.isUpdateRelatedArtifacts() );
+ scanTask.setResource( repositoryTask.getResource() );
+ scanTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTimeMs() );
+ 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( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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.
+ */
+
+/*
+ * 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;
+
+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.TreeMap;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@XmlRootElement(name = "securityConfiguration")
+@Schema(name = "SecurityConfiguration", description = "Security configuration attributes.")
+public class SecurityConfiguration implements Serializable
+{
+ private static final long serialVersionUID = -4186866365979053029L;
+
+ private List<String> activeUserManagers = new ArrayList<>( );
+ private List<String> activeRbacManagers = new ArrayList<>( );
+ private Map<String,String> properties = new TreeMap<>( );
+ private boolean userCacheEnabled=false;
+ private boolean ldapActive=false;
+
+ public SecurityConfiguration() {
+
+ }
+
+ public static SecurityConfiguration ofRedbackConfiguration( RedbackRuntimeConfiguration configuration ) {
+ SecurityConfiguration secConfig = new SecurityConfiguration( );
+ secConfig.setActiveRbacManagers( configuration.getRbacManagerImpls() );
+ secConfig.setActiveUserManagers( configuration.getUserManagerImpls() );
+ secConfig.setProperties( configuration.getConfigurationProperties() );
+ boolean rbLdapActive = configuration.getUserManagerImpls( ).stream( ).anyMatch( um -> um.contains( "ldap" ) );
+ secConfig.setLdapActive( rbLdapActive );
+ secConfig.setUserCacheEnabled( configuration.isUseUsersCache() );
+ return secConfig;
+ }
+
+ @Schema(name="active_user_managers", description = "List of ids of the active user managers")
+ public List<String> getActiveUserManagers( )
+ {
+ return activeUserManagers;
+ }
+
+ public void setActiveUserManagers( List<String> activeUserManagers )
+ {
+ this.activeUserManagers = new ArrayList<>( activeUserManagers );
+ }
+
+ public void addSelectedUserManager(String userManager) {
+ this.activeUserManagers.add( userManager );
+ }
+
+ @Schema(name="active_rbac_managers", description = "List of ids of the active rbac managers")
+ public List<String> getActiveRbacManagers( )
+ {
+ return activeRbacManagers;
+ }
+
+ public void setActiveRbacManagers( List<String> activeRbacManagers )
+ {
+ this.activeRbacManagers = new ArrayList<>( activeRbacManagers );
+ }
+
+ public void addSelectedRbacManager(String rbacManager) {
+ this.activeRbacManagers.add( rbacManager );
+ }
+
+ @Schema(description = "Map of all security properties")
+ public Map<String, String> getProperties( )
+ {
+ return properties;
+ }
+
+ public void setProperties( Map<String, String> 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.")
+ public boolean isUserCacheEnabled( )
+ {
+ return userCacheEnabled;
+ }
+
+ public void setUserCacheEnabled( boolean userCacheEnabled )
+ {
+ this.userCacheEnabled = userCacheEnabled;
+ }
+
+ @Schema(name="ldap_active", description = "True, if LDAP is used as user manager")
+ public boolean isLdapActive( )
+ {
+ return ldapActive;
+ }
+
+ public void setLdapActive( boolean ldapActive )
+ {
+ this.ldapActive = ldapActive;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ SecurityConfiguration that = (SecurityConfiguration) o;
+
+ if ( userCacheEnabled != that.userCacheEnabled ) return false;
+ if ( ldapActive != that.ldapActive ) return false;
+ if ( !activeUserManagers.equals( that.activeUserManagers ) ) return false;
+ if ( !activeRbacManagers.equals( that.activeRbacManagers ) ) return false;
+ return properties.equals( that.properties );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = activeUserManagers.hashCode( );
+ result = 31 * result + activeRbacManagers.hashCode( );
+ result = 31 * result + properties.hashCode( );
+ result = 31 * result + ( userCacheEnabled ? 1 : 0 );
+ result = 31 * result + ( ldapActive ? 1 : 0 );
+ return result;
+ }
+
+ @SuppressWarnings( "StringBufferReplaceableByString" )
+ @Override
+ public String toString( )
+ {
+ final StringBuilder sb = new StringBuilder( "SecurityConfiguration{" );
+ sb.append( "active_user_managers=" ).append( activeUserManagers );
+ sb.append( ", active_rbac_managers=" ).append( activeRbacManagers );
+ sb.append( ", properties=" ).append( properties );
+ sb.append( ", user_cache_enabled=" ).append( userCacheEnabled );
+ sb.append( ", ldap_active=" ).append( ldapActive );
+ sb.append( '}' );
+ return sb.toString( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.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 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.stream.Collectors;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@XmlRootElement(name = "validationError")
+@Schema(name = "ValidationError", description = "A validation error.")
+public class ValidationError implements Serializable
+{
+ private static final long serialVersionUID = 2079020598090660171L;
+
+ String key;
+ String field;
+ String category;
+ String type;
+ List<String> parameter;
+
+
+ public ValidationError( )
+ {
+ }
+
+ public ValidationError( String key, String field, String category, String type, List<String> parameter) {
+ this.key = key;
+ this.field = field;
+ this.category = category;
+ this.type = type;
+ if (parameter==null) {
+ this.parameter = new ArrayList<>( );
+ } else
+ {
+ this.parameter = parameter;
+ }
+ }
+
+ /**
+ * Creates a new instance based on the given error
+ * @param error the error instance
+ * @return
+ */
+ public static ValidationError of( org.apache.archiva.repository.validation.ValidationError error ) {
+ return error != null ? new ValidationError( error.getErrorKey( ), error.getAttribute( ), error.getCategory( ),
+ error.getType( ), error.getArguments( ).stream( ).map( Object::toString ).collect( Collectors.toList( ) ) )
+ : new ValidationError( );
+ }
+
+ /**
+ * Creates a new instance based on the field name and the error instance
+ * @param fieldName the name of the field to which the error applies
+ * @param error the error definition
+ * @return a new validation error instance
+ */
+ public static ValidationError of( String fieldName, org.apache.archiva.repository.validation.ValidationError error ) {
+ return error != null ? new ValidationError( error.getErrorKey( ), fieldName, error.getCategory( ),
+ error.getType( ), error.getArguments( ).stream( ).map( Object::toString ).collect( Collectors.toList( ) ) )
+ : new ValidationError( );
+ }
+
+ @Schema(name="key", description = "The full key of the validation error")
+ public String getKey( )
+ {
+ return key;
+ }
+
+ public void setKey( String key )
+ {
+ this.key = key;
+ }
+
+ @Schema(name="field", description = "The name of the field where the error was detected")
+ public String getField( )
+ {
+ return field;
+ }
+
+ public void setField( String field )
+ {
+ this.field = field;
+ }
+
+ @Schema(name="category", description = "The name of the category this error is assigned to")
+ public String getCategory( )
+ {
+ return category;
+ }
+
+ public void setCategory( String category )
+ {
+ this.category = category;
+ }
+
+ @Schema(name="type", description = "The type of the error. This is a unique string that defines the type of error, e.g. empty, bad_number_range, ... .")
+ public String getType( )
+ {
+ return type;
+ }
+
+ public void setType( String type )
+ {
+ this.type = type;
+ }
+
+ @Schema(name="parameter", description = "The list of parameters, that can be used to create a translated error message")
+ public List<String> getParameter( )
+ {
+ return parameter;
+ }
+
+ public void setParameter( List<String> parameter )
+ {
+ this.parameter = parameter;
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.model.repository;/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import java.time.Period;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="ArtifactCleanupInfo",description = "Information for artifact cleanup feature of repository")
+public class ArtifactCleanupInfo
+{
+ boolean deleteReleasedSnapshots;
+ Period retentionPeriod;
+ int retentionCount;
+
+ @Schema(name="delete_released_snapshots",description = "True, if snapshots are deleted after a release was published")
+ public boolean isDeleteReleasedSnapshots( )
+ {
+ return deleteReleasedSnapshots;
+ }
+
+ public void setDeleteReleasedSnapshots( boolean deleteReleasedSnapshots )
+ {
+ this.deleteReleasedSnapshots = deleteReleasedSnapshots;
+ }
+
+ @Schema(name="retention_period",description = "Time, after that snapshot artifacts are marked for deletion")
+ public Period getRetentionPeriod( )
+ {
+ return retentionPeriod;
+ }
+
+ public void setRetentionPeriod( Period retentionPeriod )
+ {
+ this.retentionPeriod = retentionPeriod;
+ }
+
+ @Schema(name="retention_count",description = "Maximum number of snapshot artifacts to keep")
+ public int getRetentionCount( )
+ {
+ return retentionCount;
+ }
+
+ public void setRetentionCount( int retentionCount )
+ {
+ this.retentionCount = retentionCount;
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.model.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;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="IndexCreationInfo",description = "Information about index creation feature of repositories")
+public class IndexCreationInfo
+{
+ private boolean skipPackedIndexCreation = false;
+ private String indexPath;
+ private String packedIndexPath;
+
+ @Schema(name="skip_packed_index_creation",description = "True, if the packed index will not be created")
+ public boolean isSkipPackedIndexCreation( )
+ {
+ return skipPackedIndexCreation;
+ }
+
+ public void setSkipPackedIndexCreation( boolean skipPackedIndexCreation )
+ {
+ this.skipPackedIndexCreation = skipPackedIndexCreation;
+ }
+
+ @Schema(name="index_path",description = "Path to the index directory relative to the repository base directory")
+ public String getIndexPath( )
+ {
+ return indexPath;
+ }
+
+ public void setIndexPath( String indexPath )
+ {
+ this.indexPath = indexPath;
+ }
+
+ @Schema(name="packed_index_path",description = "Path to the packed index directory relative to the repository base directory")
+ public String getPackedIndexPath( )
+ {
+ return packedIndexPath;
+ }
+
+ public void setPackedIndexPath( String packedIndexPath )
+ {
+ this.packedIndexPath = packedIndexPath;
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.model.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;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="RemoteIndexInfo",description = "Information about remote indexes")
+public class RemoteIndexInfo
+{
+ private boolean downloadRemoteIndex = false;
+ private String indexUri;
+
+ @Schema(name="download_remote_index",description = "True, if the index will be downloaded from the remote repository")
+ public boolean isDownloadRemoteIndex( )
+ {
+ return downloadRemoteIndex;
+ }
+
+ public void setDownloadRemoteIndex( boolean downloadRemoteIndex )
+ {
+ this.downloadRemoteIndex = downloadRemoteIndex;
+ }
+
+ @Schema(name="index_uri", description = "The URI that specifies the path to the remote index")
+ public String getIndexUri( )
+ {
+ return indexUri;
+ }
+
+ public void setIndexUri( String indexUri )
+ {
+ this.indexUri = indexUri;
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.model.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;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="StagingInfo",description = "Information about staging feature of a repository")
+public class StagingInfo
+{
+ private String stagingRepository;
+ private boolean stageRepoNeeded;
+
+ @Schema(name="staging_repo",description = "The repository id of the staging repository")
+ public String getStagingRepository( )
+ {
+ return stagingRepository;
+ }
+
+ public void setStagingRepository( String stagingRepository )
+ {
+ this.stagingRepository = stagingRepository;
+ }
+
+ @Schema(name="stage_repo_needed",description = "True, if this repository needs a staging repository")
+ public boolean isStageRepoNeeded( )
+ {
+ return stageRepoNeeded;
+ }
+
+ public void setStageRepoNeeded( boolean stageRepoNeeded )
+ {
+ this.stageRepoNeeded = stageRepoNeeded;
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.svc;
+/*
+ * 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.rest.api.v2.model.ValidationError;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Martin Stockhammer
+ * @since 3.0
+ */
+@XmlRootElement( name = "archivaRestError" )
+@Schema(name="ArchivaRestError", description = "Contains a list of error messages that resulted from the current REST call")
+public class ArchivaRestError
+ implements Serializable
+{
+
+ private static final long serialVersionUID = -8892617571273167067L;
+ private List<ErrorMessage> errorMessages = new ArrayList<>( 1 );
+ private List<ValidationError> validationErrors;
+
+ public ArchivaRestError()
+ {
+ // no op
+ }
+
+ public ArchivaRestError( ArchivaRestServiceException e )
+ {
+ errorMessages.addAll( e.getErrorMessages() );
+ if ( e.getErrorMessages().isEmpty() && StringUtils.isNotEmpty( e.getMessage() ) )
+ {
+ errorMessages.add( new ErrorMessage( e.getMessage(), null ) );
+ }
+ if (e instanceof ValidationException) {
+ this.validationErrors = ( (ValidationException) e ).getValidationErrors( );
+ }
+ }
+
+ public ArchivaRestError( ValidationException e )
+ {
+ errorMessages.addAll( e.getErrorMessages() );
+ if ( e.getErrorMessages().isEmpty() && StringUtils.isNotEmpty( e.getMessage() ) )
+ {
+ errorMessages.add( new ErrorMessage( e.getMessage(), null ) );
+ }
+ this.validationErrors = e.getValidationErrors( );
+ }
+
+ @Schema(name="error_messages", description = "The list of errors that occurred while processing the REST request")
+ public List<ErrorMessage> getErrorMessages()
+ {
+ return errorMessages;
+ }
+
+ public void setErrorMessages( List<ErrorMessage> errorMessages )
+ {
+ this.errorMessages = errorMessages;
+ }
+
+ public void addErrorMessage( ErrorMessage errorMessage )
+ {
+ this.errorMessages.add( errorMessage );
+ }
+
+ @Schema( name = "has_validation_errors", description = "True, if the error contains validation errors" )
+ public boolean hasValidationErrors( )
+ {
+ return this.validationErrors != null && this.validationErrors.size( ) > 0;
+ }
+
+ @Schema( name = "validation_errors", description = "The list of validation errors")
+ public List<ValidationError> getValidationErrors() {
+ return hasValidationErrors() ? this.validationErrors : Collections.emptyList( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.svc;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Generic REST Service Exception that contains error information.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+public class ArchivaRestServiceException extends Exception
+{
+ private int httpErrorCode = 500;
+
+ private List<ErrorMessage> errorMessages = new ArrayList<ErrorMessage>(0);
+
+ public ArchivaRestServiceException( String s )
+ {
+ super( s );
+ }
+
+ public ArchivaRestServiceException( String s, int httpErrorCode )
+ {
+ super( s );
+ this.httpErrorCode = httpErrorCode;
+ }
+
+ public ArchivaRestServiceException( ErrorMessage errorMessage )
+ {
+ errorMessages.add( errorMessage );
+ }
+
+ public ArchivaRestServiceException( ErrorMessage errorMessage, int httpResponseCode )
+ {
+ this.httpErrorCode = httpResponseCode;
+ errorMessages.add( errorMessage );
+ }
+
+ public ArchivaRestServiceException( List<ErrorMessage> errorMessage )
+ {
+ errorMessages.addAll( errorMessage );
+ }
+
+ public ArchivaRestServiceException( List<ErrorMessage> errorMessage, int httpResponseCode )
+ {
+ this.httpErrorCode = httpResponseCode;
+ errorMessages.addAll( errorMessage );
+ }
+
+ public int getHttpErrorCode()
+ {
+ return httpErrorCode;
+ }
+
+ public void setHttpErrorCode( int httpErrorCode )
+ {
+ this.httpErrorCode = httpErrorCode;
+ }
+
+ public List<ErrorMessage> getErrorMessages()
+ {
+ if ( errorMessages == null )
+ {
+ this.errorMessages = new ArrayList<ErrorMessage>();
+ }
+ return errorMessages;
+ }
+
+ public void setErrorMessages( List<ErrorMessage> errorMessages )
+ {
+ this.errorMessages = errorMessages;
+ }
+
+ public void addErrorMessage( ErrorMessage errorMessage )
+ {
+ this.errorMessages.add( errorMessage );
+ }
+
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.svc;/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface ErrorKeys
+{
+
+ String PREFIX = "archiva.";
+
+ String VALIDATION_ERROR = PREFIX + "validation_error";
+
+ String REPOSITORY_GROUP_PREFIX = PREFIX + "repository_group.";
+ String REPOSITORY_PREFIX = PREFIX + "repository.";
+
+ String INVALID_RESULT_SET_ERROR = "archiva.result_set.invalid";
+ String REPOSITORY_ADMIN_ERROR = "archiva.repositoryadmin.error";
+ String LDAP_CF_INIT_FAILED = "archiva.ldap.cf.init.failed";
+ String LDAP_USER_MAPPER_INIT_FAILED = "archiva.ldap.usermapper.init.failed";
+ String LDAP_COMMUNICATION_ERROR = "archiva.ldap.communication_error";
+ String LDAP_INVALID_NAME = "archiva.ldap.invalid_name";
+ String LDAP_GENERIC_ERROR = "archiva.ldap.generic_error";
+ String LDAP_SERVICE_UNAVAILABLE = "archiva.ldap.service_unavailable";
+ String LDAP_SERVICE_AUTHENTICATION_FAILED = "archiva.ldap.authentication.failed";
+ String LDAP_SERVICE_AUTHENTICATION_NOT_SUPPORTED = "archiva.ldap.authentication.not_supported";
+ String LDAP_SERVICE_NO_PERMISSION = "archiva.ldap.no_permissions";
+
+ String PROPERTY_NOT_FOUND = "archiva.property.not.found";
+
+ String MISSING_DATA = "archiva.missing.data";
+
+ 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_UPDATE_FAILED = REPOSITORY_GROUP_PREFIX + "update.failed";
+
+ String REPOSITORY_GROUP_DELETE_FAILED = REPOSITORY_GROUP_PREFIX + "delete.failed";
+ String REPOSITORY_NOT_FOUND = REPOSITORY_PREFIX + "notfound";
+ String REPOSITORY_MANAGED_NOT_FOUND = REPOSITORY_PREFIX + "managed.notfound";
+ String REPOSITORY_REMOTE_NOT_FOUND = REPOSITORY_PREFIX + "remote.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";
+ String ARTIFACT_EXISTS_AT_DEST = REPOSITORY_PREFIX + "artifact.dest.exists";
+ String REPOSITORY_REMOTE_INDEX_DOWNLOAD_FAILED = REPOSITORY_PREFIX + "remote.index.download_failed";
+ String REPOSITORY_WRONG_TYPE = REPOSITORY_PREFIX + "wrong_type";
+ String REPOSITORY_DELETE_FAILED = REPOSITORY_PREFIX + "delete.failed";
+ String REPOSITORY_INVALID_ID = REPOSITORY_PREFIX + "invalid.id";
+ String REPOSITORY_ID_EXISTS = REPOSITORY_PREFIX + "id.exists";
+ String REPOSITORY_UPDATE_FAILED = REPOSITORY_PREFIX + "update.failed";
+ String ARTIFACT_NOT_FOUND = REPOSITORY_PREFIX + "artifact.notfound";
+ String REPOSITORY_LAYOUT_ERROR = REPOSITORY_PREFIX + "layout.error";
+
+ String ARTIFACT_COPY_ERROR = REPOSITORY_PREFIX + "artifact.copy.error";
+
+ /**
+ * The given user was not found
+ * Parameters:
+ * - User Id
+ */
+ String USER_NOT_FOUND = PREFIX+"user.not_found";
+
+ /**
+ * Error from UserManager
+ * Parameters:
+ * - Error Message
+ */
+ String USER_MANAGER_ERROR = PREFIX+"user_manager.error";
+
+ /**
+ * Permission to the repository denied.
+ * Parameters:
+ * - Repository Id
+ * - Permission ID
+ */
+ String PERMISSION_REPOSITORY_DENIED = PREFIX + "permission.repository.denied";
+
+ /**
+ * A generic authorization error thrown during the authorization check.
+ * Parameters:
+ * - Error message
+ */
+ String AUTHORIZATION_ERROR = PREFIX + "authorization.error";
+
+ /**
+ * When the operation needs authentication, but not authenticated user was found in the request context.
+ */
+ String NOT_AUTHENTICATED = PREFIX + "user.not_authenticated";
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.svc;
+/*
+ * 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;
+
+/**
+ * @author Olivier Lamy
+ * @author Martin Stockhammer
+ * @since 3.0
+ */
+@XmlRootElement( name = "errorMessage" )
+@Schema(name="ErrorMessage",description = "Information about the error, that occurred while processing the REST request.")
+public class ErrorMessage
+ implements Serializable
+{
+ private String errorKey = "";
+
+ private String[] args = EMPTY;
+
+ private String message = "";
+
+ private static final String[] EMPTY = new String[0];
+
+ public ErrorMessage()
+ {
+ // no op
+ }
+
+ public ErrorMessage( String errorKey )
+ {
+ this.errorKey = errorKey;
+ this.args = EMPTY;
+ }
+
+ public ErrorMessage( String errorKey, String[] args )
+ {
+ this.errorKey = errorKey;
+ this.args = args;
+ }
+
+ public static ErrorMessage of(String errorKey, String... args) {
+ return new ErrorMessage( errorKey, args );
+ }
+
+ @Schema(name="error_key", description = "The key of the error message. If this is empty, the message message must be set.")
+ public String getErrorKey()
+ {
+ return errorKey;
+ }
+
+ public void setErrorKey( String errorKey )
+ {
+ this.errorKey = errorKey;
+ }
+
+ @Schema(description = "Parameters that can be filled to the translated error message")
+ public String[] getArgs()
+ {
+ return args;
+ }
+
+ public void setArgs( String[] args )
+ {
+ this.args = args;
+ }
+
+ @Schema(description = "Full error message. Either additional to the key in the default language, or if the message is without key.")
+ public String getMessage()
+ {
+ return message;
+ }
+
+ public void setMessage( String message )
+ {
+ this.message = message;
+ }
+
+ public ErrorMessage message( String message )
+ {
+ this.message = message;
+ return this;
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.svc;
+/*
+ * 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.parameters.RequestBody;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.redback.authorization.RedbackAuthorization;
+import org.apache.archiva.rest.api.v2.model.RepositoryGroup;
+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.Response;
+import java.util.List;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.apache.archiva.rest.api.v2.svc.RestConfiguration.DEFAULT_PAGE_LIMIT;
+
+/**
+ * Endpoint for repository groups that combine multiple repositories into a single virtual repository.
+ *
+ * @author Olivier Lamy
+ * @author Martin Stockhammer
+ * @since 3.0
+ */
+@Path( "/repository_groups" )
+@Schema( name = "RepositoryGroups", description = "Managing of repository groups or virtual repositories" )
+public interface RepositoryGroupService
+{
+ @Path( "" )
+ @GET
+ @Produces( {APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Returns all repository group entries.",
+ 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<RepositoryGroup> getRepositoriesGroups( @QueryParam( "q" ) @DefaultValue( "" ) String searchTerm,
+ @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
+ @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
+ @QueryParam( "orderBy" ) @DefaultValue( "id" ) List<String> orderBy,
+ @QueryParam( "order" ) @DefaultValue( "asc" ) String order )
+ throws ArchivaRestServiceException;
+
+ @Path( "{id}" )
+ @GET
+ @Produces( {APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Returns a single repository group configuration.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the configuration is returned",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.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 group with the given id does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ RepositoryGroup getRepositoryGroup( @PathParam( "id" ) String repositoryGroupId )
+ throws ArchivaRestServiceException;
+
+ @Path( "" )
+ @POST
+ @Consumes( {APPLICATION_JSON} )
+ @Produces( {APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Creates a new group entry.",
+ requestBody =
+ @RequestBody( required = true, description = "The configuration of the repository group.",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.class ) )
+ )
+ ,
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "201",
+ description = "If the repository group was created",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.class ) )
+ ),
+ @ApiResponse( responseCode = "303", description = "The repository group exists already",
+ headers = {
+ @Header( name = "Location", description = "The URL of existing group", schema = @Schema( type = "string" ) )
+ }
+ ),
+ @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 = "422", description = "The body data is not valid",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ RepositoryGroup addRepositoryGroup( RepositoryGroup repositoryGroup )
+ throws ArchivaRestServiceException;
+
+ @Path( "{id}" )
+ @PUT
+ @Consumes( {APPLICATION_JSON} )
+ @Produces( {APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Returns all repository group entries.",
+ requestBody =
+ @RequestBody( required = true, description = "The configuration of the repository group.",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.class ) )
+ )
+ ,
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the group is returned",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.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 group with the given id does not exist",
+ 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 ) ) )
+ }
+ )
+ RepositoryGroup updateRepositoryGroup( @PathParam( "id" ) String groupId, RepositoryGroup repositoryGroup )
+ throws ArchivaRestServiceException;
+
+ @Path( "{id}" )
+ @DELETE
+ @Produces( {APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Deletes the repository group entry with the given id.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the group was deleted"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete the group",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The group with the given id does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ }
+ )
+ Response deleteRepositoryGroup( @PathParam( "id" ) String repositoryGroupId )
+ throws ArchivaRestServiceException;
+
+ @Path( "{id}/repositories/{repositoryId}" )
+ @PUT
+ @Produces( {APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Adds the repository with the given id to the repository group.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the repository was added or if it was already part of the group"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete the group",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The group with the given id does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ }
+ )
+ RepositoryGroup addRepositoryToGroup( @PathParam( "id" ) String repositoryGroupId,
+ @PathParam( "repositoryId" ) String repositoryId )
+ throws ArchivaRestServiceException;
+
+ @Path( "{id}/repositories/{repositoryId}" )
+ @DELETE
+ @Produces( {APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Removes the repository with the given id from the repository group.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the repository was removed."
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete the group",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "Either the group with the given id does not exist, or the repository was not part of the group.",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ }
+ )
+ RepositoryGroup deleteRepositoryFromGroup( @PathParam( "id" ) String repositoryGroupId,
+ @PathParam( "repositoryId" ) String repositoryId )
+ throws ArchivaRestServiceException;
+
+
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.svc;
+/*
+ * 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.v2.model.Repository;
+import org.apache.archiva.rest.api.v2.model.RepositoryStatistics;
+import org.apache.archiva.rest.api.v2.model.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.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.List;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.apache.archiva.rest.api.v2.svc.RestConfiguration.DEFAULT_PAGE_LIMIT;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Path( "repositories" )
+@Tag(name = "v2")
+@Tag(name = "v2/Repositories")
+@Schema(name="RepositoryService",description = "Manage repositories of all types")
+public interface RepositoryService
+{
+
+ @Path( "" )
+ @GET
+ @Produces( {APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Returns all managed repositories.",
+ parameters = {
+ @Parameter( name = "q", description = "Search term" ),
+ @Parameter( name = "offset", description = "The offset of the first element returned" ),
+ @Parameter( name = "limit", description = "Maximum number of items to return in the response" ),
+ @Parameter( name = "orderBy", description = "List of attribute used for sorting (key, value)" ),
+ @Parameter( name = "order", description = "The sort order. Either ascending (asc) or descending (desc)" ),
+ @Parameter( name = "locale", description = "The locale for name and description" )
+ },
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the list could be returned",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = PagedResult.class ) )
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ PagedResult<Repository> getRepositories( @QueryParam( "q" ) @DefaultValue( "" ) String searchTerm,
+ @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
+ @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
+ @QueryParam( "orderBy" ) @DefaultValue( "id" ) List<String> orderBy,
+ @QueryParam( "order" ) @DefaultValue( "asc" ) String order,
+ @QueryParam( "locale" ) String localeString) throws ArchivaRestServiceException;
+
+ @Path( "managed/{id}/statistics" )
+ @GET
+ @Produces( {APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Returns repository statistic data.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the statistics could be returned",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryStatistics.class ) )
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The repository does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ RepositoryStatistics getManagedRepositoryStatistics( @PathParam( "id" ) String repositoryId )
+ throws ArchivaRestServiceException;
+
+ @Path ("managed/{id}/scan/schedule")
+ @POST
+ @Produces ({ APPLICATION_JSON })
+ @Consumes({ APPLICATION_JSON })
+ @RedbackAuthorization (permissions = ArchivaRoleConstants.OPERATION_RUN_INDEXER)
+ @Operation( summary = "Returns repository statistic data.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the statistics could be returned"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The repository does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ Response scheduleRepositoryScan( @PathParam ("id") String repositoryId,
+ @QueryParam ("fullScan") boolean fullScan )
+ throws ArchivaRestServiceException;
+
+
+ @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;
+
+
+ @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 = "Cancels and removes all tasks for the given repository.",
+ 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;
+
+
+
+ @Path ("remote/{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.",
+ parameters = {
+ @Parameter( name = "full", description = "If true, download the full index, otherwise try a update 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( "immediate" ) boolean immediately,
+ @QueryParam ("full") boolean full, @Context UriInfo uriInfo )
+ throws ArchivaRestServiceException;
+
+
+ @Path ("remote/index/downloads")
+ @GET
+ @Produces ({ APPLICATION_JSON })
+ @RedbackAuthorization (permissions = ArchivaRoleConstants.OPERATION_RUN_INDEXER)
+ @Operation( summary = "Returns a list of running downloads from the remote repository.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the artifact was deleted"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ List<String> getRunningRemoteDownloads();
+
+
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.svc;/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface RestConfiguration
+{
+ String DEFAULT_PAGE_LIMIT = "10";
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.svc;
+/*
+ * 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.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.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.components.rest.model.PropertyEntry;
+import org.apache.archiva.redback.authorization.RedbackAuthorization;
+import org.apache.archiva.rest.api.v2.model.BeanInformation;
+import org.apache.archiva.rest.api.v2.model.CacheConfiguration;
+import org.apache.archiva.rest.api.v2.model.LdapConfiguration;
+import org.apache.archiva.rest.api.v2.model.SecurityConfiguration;
+import org.apache.archiva.security.common.ArchivaRoleConstants;
+
+import javax.ws.rs.Consumes;
+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.Response;
+import java.util.List;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.apache.archiva.rest.api.v2.svc.RestConfiguration.DEFAULT_PAGE_LIMIT;
+
+/**
+ *
+ * Service for configuration of redback and security related settings.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Path( "/security" )
+@Tag(name = "v2")
+@Tag(name = "v2/Security")
+@SecurityRequirement(name = "BearerAuth")
+public interface SecurityConfigurationService
+{
+ @Path("config")
+ @GET
+ @Produces({ APPLICATION_JSON })
+ @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
+ @Operation( summary = "Returns the security configuration that is currently active.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the configuration could be retrieved",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = SecurityConfiguration.class))
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ }
+ )
+ SecurityConfiguration getConfiguration()
+ throws ArchivaRestServiceException;
+
+ @Path("config")
+ @PUT
+ @Consumes({ APPLICATION_JSON })
+ @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
+ @Operation( summary = "Updates the security configuration.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the configuration was updated"
+ ),
+ @ApiResponse( responseCode = "422", description = "Invalid content data",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to update the configuration",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ }
+ )
+ SecurityConfiguration updateConfiguration( SecurityConfiguration newConfiguration)
+ throws ArchivaRestServiceException;
+
+
+ @Path( "config/properties" )
+ @GET
+ @Produces( { APPLICATION_JSON } )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Returns all configuration properties. The result is paged.",
+ 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<PropertyEntry> getConfigurationProperties( @QueryParam("q") @DefaultValue( "" ) String searchTerm,
+ @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
+ @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
+ @QueryParam( "orderBy") @DefaultValue( "key" ) List<String> orderBy,
+ @QueryParam("order") @DefaultValue( "asc" ) String order ) throws ArchivaRestServiceException;
+
+ @Path("config/properties/{propertyName}")
+ @GET
+ @Produces({ APPLICATION_JSON })
+ @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
+ @Operation( summary = "Returns a single configuration property value.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ parameters = {
+ @Parameter(in = ParameterIn.PATH, name="propertyName", description = "The name of the property to get the value for")
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the configuration could be retrieved",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = PropertyEntry.class))
+ ),
+ @ApiResponse( responseCode = "404", description = "The given property name does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ }
+ )
+ PropertyEntry getConfigurationProperty( @PathParam ( "propertyName" ) String propertyName)
+ throws ArchivaRestServiceException;
+
+
+ @Path("config/properties/{propertyName}")
+ @PUT
+ @Consumes({ APPLICATION_JSON})
+ @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
+ @Operation( summary = "Updates a single property value of the security configuration.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ parameters = {
+ @Parameter(in = ParameterIn.PATH, name="propertyName", description = "The name of the property to update")
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the property value was updated."
+ ),
+ @ApiResponse( responseCode = "400", description = "The body data is not valid",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ @ApiResponse( responseCode = "404", description = "The given property name does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ }
+ )
+ Response updateConfigurationProperty( @PathParam ( "propertyName" ) String propertyName, PropertyEntry propertyValue)
+ throws ArchivaRestServiceException;
+
+ @Path("config/ldap")
+ @GET
+ @Produces({ APPLICATION_JSON })
+ @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
+ @Operation( summary = "Returns the LDAP configuration that is currently active.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the configuration could be retrieved",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = LdapConfiguration.class))
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ }
+ )
+ LdapConfiguration getLdapConfiguration( ) throws ArchivaRestServiceException;
+
+ @Path("config/ldap")
+ @PUT
+ @Consumes({ APPLICATION_JSON })
+ @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
+ @Operation( summary = "Updates the LDAP configuration that is currently active.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the configuration was updated"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to update the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ }
+ )
+ LdapConfiguration updateLdapConfiguration( LdapConfiguration configuration ) throws ArchivaRestServiceException;
+
+ @Path("config/ldap/verify")
+ @POST
+ @Consumes({ APPLICATION_JSON })
+ @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
+ @Operation( summary = "Checks the given LDAP configuration.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the check was successful"
+ ),
+ @ApiResponse( responseCode = "400",
+ description = "If the check was not successful",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class ))
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to update the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ }
+ )
+ Response verifyLdapConfiguration( LdapConfiguration configuration ) throws ArchivaRestServiceException;
+
+ @Path("config/cache")
+ @GET
+ @Produces({ APPLICATION_JSON })
+ @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
+ @Operation( summary = "Returns the cache configuration that is currently active.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the configuration could be retrieved",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = CacheConfiguration.class))
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ }
+ )
+ CacheConfiguration getCacheConfiguration( ) throws ArchivaRestServiceException;
+
+ @Path("config/cache")
+ @PUT
+ @Consumes({ APPLICATION_JSON })
+ @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
+ @Operation( summary = "Updates the LDAP configuration that is currently active.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the configuration was updated"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to update the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ }
+ )
+ CacheConfiguration updateCacheConfiguration( CacheConfiguration cacheConfiguration ) throws ArchivaRestServiceException;
+
+
+ @Path("user_managers")
+ @GET
+ @Produces({ APPLICATION_JSON })
+ @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
+ @Operation( summary = "Returns the available user manager implementations.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the list could be retrieved",
+ content = @Content(mediaType = APPLICATION_JSON, array = @ArraySchema(
+ schema = @Schema(implementation = BeanInformation.class)))
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ }
+ )
+ List<BeanInformation> getAvailableUserManagers()
+ throws ArchivaRestServiceException;
+
+ @Path("rbac_managers")
+ @GET
+ @Produces({ APPLICATION_JSON })
+ @RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
+ @Operation( summary = "Returns the available RBAC manager implementations.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the list could be retrieved",
+ content = @Content(mediaType = APPLICATION_JSON, array = @ArraySchema(
+ schema = @Schema(implementation = BeanInformation.class)))
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ }
+ )
+ List<BeanInformation> getAvailableRbacManagers()
+ throws ArchivaRestServiceException;
+
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.svc;
+/*
+ * 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.repository.Repository;
+import org.apache.archiva.repository.validation.ValidationResponse;
+import org.apache.archiva.rest.api.v2.model.ValidationError;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Exception is thrown
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class ValidationException extends ArchivaRestServiceException
+{
+ public static final int DEFAULT_CODE = 422;
+
+ public static final ErrorMessage DEFAULT_MESSAGE = new ErrorMessage( ErrorKeys.VALIDATION_ERROR );
+
+ private List<ValidationError> validationErrors;
+
+ public ValidationException( )
+ {
+ super( DEFAULT_MESSAGE, DEFAULT_CODE );
+ }
+
+ public ValidationException( int errorCode )
+ {
+ super( DEFAULT_MESSAGE, errorCode );
+ }
+
+ public ValidationException( List<ValidationError> errors )
+ {
+ super( DEFAULT_MESSAGE, DEFAULT_CODE );
+ this.validationErrors = errors;
+ }
+
+ public static ValidationException of( List<org.apache.archiva.repository.validation.ValidationError> errorList )
+ {
+ return new ValidationException( errorList.stream( ).map( ValidationError::of ).collect( Collectors.toList( ) ) );
+ }
+
+ public static ValidationException of( Map<String, List<org.apache.archiva.repository.validation.ValidationError>> errorMap )
+ {
+ return new ValidationException( errorMap.entrySet( ).stream( )
+ .flatMap( v -> v.getValue( ).stream( ).map( k -> ValidationError.of(v.getKey(), k)))
+ .collect( Collectors.toList( ) ) );
+ }
+
+ public static <R extends Repository> ValidationException of( ValidationResponse<R> result )
+ {
+ if ( result.isValid( ) )
+ {
+ return new ValidationException( );
+ }
+ else
+ {
+ return new ValidationException( result.getResult( ).entrySet( ).stream( ).flatMap(
+ v -> v.getValue( ).stream( ).map( e -> ValidationError.of( v.getKey( ), e ) ) ).collect( Collectors.toList( ) ) );
+ }
+ }
+
+ public List<ValidationError> getValidationErrors( )
+ {
+ return validationErrors == null ? Collections.emptyList( ) : validationErrors;
+ }
+
+ public void setValidationErrors( List<ValidationError> validationErrors )
+ {
+ this.validationErrors = validationErrors;
+ }
+
+ public void addValidationError( ValidationError error )
+ {
+ if ( this.validationErrors == null )
+ {
+ this.validationErrors = new ArrayList<>( );
+ }
+ this.validationErrors.add( error );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.api.v2.svc.maven;
+/*
+ * 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.v2.model.FileInfo;
+import org.apache.archiva.rest.api.v2.model.MavenManagedRepository;
+import org.apache.archiva.rest.api.v2.model.MavenManagedRepositoryUpdate;
+import org.apache.archiva.rest.api.v2.svc.ArchivaRestError;
+import org.apache.archiva.rest.api.v2.svc.ArchivaRestServiceException;
+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.v2.svc.RestConfiguration.DEFAULT_PAGE_LIMIT;
+
+/**
+ * Service interface for managing managed maven repositories
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Schema( name = "ManagedRepositoryService", description = "Managing and configuration of managed repositories" )
+@Path( "repositories/maven/managed" )
+@Tag(name = "v2")
+@Tag(name = "v2/Repositories")
+public interface MavenManagedRepositoryService
+{
+ @Path( "" )
+ @GET
+ @Produces( {APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Returns all managed repositories.",
+ parameters = {
+ @Parameter( name = "q", description = "Search term" ),
+ @Parameter( name = "offset", description = "The offset of the first element returned" ),
+ @Parameter( name = "limit", description = "Maximum number of items to return in the response" ),
+ @Parameter( name = "orderBy", description = "List of attribute used for sorting (key, value)" ),
+ @Parameter( name = "order", description = "The sort order. Either ascending (asc) or descending (desc)" )
+ },
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the list could be returned",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = PagedResult.class ) )
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ PagedResult<MavenManagedRepository> getManagedRepositories(
+ @QueryParam( "q" ) @DefaultValue( "" ) String searchTerm,
+ @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
+ @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
+ @QueryParam( "orderBy" ) @DefaultValue( "id" ) List<String> orderBy,
+ @QueryParam( "order" ) @DefaultValue( "asc" ) String order )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "{id}" )
+ @GET
+ @Produces( {MediaType.APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Returns the managed repository with the given id.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the managed repository could be returned",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ MavenManagedRepository getManagedRepository( @PathParam( "id" ) String repositoryId )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "{id}" )
+ @DELETE
+ @Produces( {MediaType.APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Deletes the managed repository with the given id.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the managed repository could be returned"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ Response deleteManagedRepository( @PathParam( "id" ) String repositoryId,
+ @QueryParam( "deleteContent" ) boolean deleteContent )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "" )
+ @POST
+ @Consumes( {MediaType.APPLICATION_JSON} )
+ @Produces( {MediaType.APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Creates the managed repository",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "201",
+ description = "If the managed repository could be created",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
+ ),
+ @ApiResponse( responseCode = "303", description = "The repository exists already",
+ headers = {
+ @Header( name = "Location", description = "The URL of existing repository ", schema = @Schema( type = "string" ) )
+ }
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "422", description = "The body data is not valid",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ MavenManagedRepository addManagedRepository( MavenManagedRepository managedRepository )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "{id}" )
+ @PUT
+ @Consumes( {MediaType.APPLICATION_JSON} )
+ @Produces( {MediaType.APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Updates the managed repository with the given id",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the managed repository could be updated",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "422", description = "The body data is not valid",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ MavenManagedRepository updateManagedRepository( @PathParam( "id" ) String repositoryId, MavenManagedRepositoryUpdate managedRepository )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "{id}/path/{filePath: .+}" )
+ @GET
+ @Produces( {MediaType.APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS, resource = "{id}")
+ @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;
+
+
+ /**
+ * Permissions are checked in impl
+ * will copy an artifact from the source repository to the target repository
+ */
+ @Path ("{srcId}/path/{path: .+}/copyto/{dstId}")
+ @POST
+ @Produces({APPLICATION_JSON})
+ @RedbackAuthorization (noPermission = true)
+ @Operation( summary = "Copies a artifact from the source repository to the destination repository",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
+ scopes = {
+ "{srcId}"
+ }
+ ),
+ @SecurityRequirement(
+ name= ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD,
+ scopes = {
+ "{dstId}"
+ }
+ )
+
+ },
+ 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( @PathParam( "srcId" ) String srcRepositoryId, @PathParam( "dstId" ) String dstRepositoryId,
+ @PathParam( "path" ) String path )
+ throws ArchivaRestServiceException;
+
+
+ @Path ("{id}/path/{path: .+}")
+ @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( @PathParam( "id" ) String repositoryId, @PathParam( "path" ) String path )
+ throws ArchivaRestServiceException;
+
+ @Path ( "{id}/co/{group}/{project}/{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 ( "group" ) String namespace, @PathParam ( "project" ) String projectId,
+ @PathParam ( "version" ) String version )
+ throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+
+
+ @Path ( "{id}/co/{group}/{project}" )
+ @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 ( "group" ) String namespace, @PathParam ( "project" ) String projectId )
+ throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+
+ @Path ( "{id}/co/{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;
+
+}
--- /dev/null
+/*
+ * 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.
+ */
+/**
+ * <p>This is the V2 REST API of Archiva. It uses JAX-RS annotations for defining the endpoints.
+ * The API is documented with OpenApi annotations.</p>
+ *
+ * <h3>Some design principles of the API and classes:</h3>
+ * <ul>
+ * <li>All services use V2 model classes. Internal models are always converted to V2 classes.</li>
+ * <li>Schema attributes use the snake case syntax (lower case with '_' as divider)</li>
+ * <li>Return code <code>200</code> and <code>201</code> (POST) is used for successful execution.</li>
+ * <li>Return code <code>403</code> is used, if the user has not the permission for the action.</li>
+ * <li>Return code <code>422</code> is used for input that has invalid data.</li>
+ * </ul>
+ *
+ * <h4>Querying entity lists</h4>
+ * <p>The main entities of a given path are retrieved on the base path.
+ * Further sub entities or entries may be retrieved via subpaths.
+ * A single entity is returned by the "{id}" path. Be careful with technical paths that are parallel to the
+ * id path. Avoid naming conflicts with the id and technical paths.
+ * Entity attributes may be retrieved by "{id}/{attribute}" path or if there are lists or collections by
+ * "{id}/mycollection/{subentryid}"</p>
+ *
+ * <ul>
+ * <li><code>GET</code> method is used for retrieving entities on the base path ""</li>
+ * <li>The query for base entities should always return a paged result and be filterable and sortable</li>
+ * <li>Query parameters for filtering, ordering and limits should be optional and proper defaults must be set</li>
+ * <li>Return code <code>200</code> is used for successful retrieval</li>
+ * <li>This action is idempotent</li>
+ * </ul>
+ *
+ * <h4>Querying single entities</h4>
+ * <p>Single entities are retrieved on the path "{id}"</p>
+ * <ul>
+ * <li><code>GET</code> method is used for retrieving a single entity. The id is always a path parameter.</li>
+ * <li>Return code <code>200</code> is used for successful retrieval</li>
+ * <li>Return code <code>404</code> is used if the entity with the given id does not exist</li>
+ * <li>This action is idempotent</li>
+ * </ul>
+ *
+ * <h4>Creating entities</h4>
+ * <p>The main entities are created on the base path "".</p>
+ * <ul>
+ * <li><code>POST</code> is used for creating new entities</li>
+ * <li>The <code>POST</code> body must always have a complete definition of the entity.</li>
+ * <li>A unique <code>id</code> or <code>name</code> attribute is required for entities. If the id is generated during POST,
+ * it must be returned by response body.</li>
+ * <li>A successful <code>POST</code> request should always return the entity definition as it would be returned by the GET request.</li>
+ * <li>Return code <code>201</code> is used for successful creation of the new entity.</li>
+ * <li>A successful response has a <code>Location</code> header with the URL for retrieving the single created entity.</li>
+ * <li>Return code <code>303</code> is used, if the entity exists already</li>
+ * <li>This action is not idempotent</li>
+ * </ul>
+ *
+ * <h4>Updating entities</h4>
+ * <p>The path for entity update must contain the '{id}' of the entity. The path should be the same as for the GET operation.</p>
+ * <ul>
+ * <li><code>PUT</code> is used for updating existing entities</li>
+ * <li>The body contains a JSON object. Only existing attributes are updated.</li>
+ * <li>A successful PUT request should return the complete entity definition as it would be returned by the GET request.</li>
+ * <li>Return code <code>200</code> is used for successful update of the new entity. Even if nothing changed.</li>
+ * <li>This action is idempotent</li>
+ * </ul>
+ *
+ * <h4>Deleting entities</h4>
+ * <p>The path for entity deletion must contain the '{id}' of the entity. The path should be the same as
+ * for the GET operation.</p>
+ * <ul>
+ * <li><code>DELETE</code> is used for deleting existing entities</li>
+ * <li>The successful operation has no request and no response body</li>
+ * <li>Return code <code>200</code> is used for successful deletion of the new entity.</li>
+ * <li>This action is not idempotent</li>
+ * </ul>
+ *
+ * <h4>Errors</h4>
+ * <ul>
+ * <li>A error uses a return code <code>>=400</code> </li>
+ * <li>All errors use the same result object ({@link org.apache.archiva.rest.api.v2.svc.ArchivaRestError}</li>
+ * <li>Error messages are returned as keys. Translation is part of the client application.</li>
+ * </ul>
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+package org.apache.archiva.rest.api.v2.svc;
\ No newline at end of file
resourcePackages:
- - org.apache.archiva.rest.api.services.v2
- - org.apache.archiva.rest.api.model.v2
+ - org.apache.archiva.rest.api.v2.svc
+ - org.apache.archiva.rest.api.v2.model
prettyPrint: true
cacheTTL: 0
+++ /dev/null
-package org.apache.archiva.rest.services.interceptors.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.rest.api.services.v2.ArchivaRestError;
-import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
-import org.springframework.stereotype.Service;
-
-import javax.ws.rs.core.Response;
-import javax.ws.rs.ext.ExceptionMapper;
-import javax.ws.rs.ext.Provider;
-
-/**
- * Maps exceptions to REST responses.
- *
- * @author Martin Stockhammer
- * @since 3.0
- */
-@Provider
-@Service( "v2.archivaRestServiceExceptionMapper" )
-public class ArchivaRestServiceExceptionMapper
- implements ExceptionMapper<ArchivaRestServiceException>
-{
- @Override
- public Response toResponse( final ArchivaRestServiceException e )
- {
- ArchivaRestError restError = new ArchivaRestError( e );
-
- Response.ResponseBuilder responseBuilder = Response.status( e.getHttpErrorCode() ).entity( restError );
- if ( e.getMessage() != null )
- {
- responseBuilder = responseBuilder.status( new Response.StatusType()
- {
- public int getStatusCode()
- {
- return e.getHttpErrorCode();
- }
-
- public Response.Status.Family getFamily()
- {
- return Response.Status.Family.familyOf( e.getHttpErrorCode( ) );
- }
-
- public String getReasonPhrase()
- {
- return e.getMessage();
- }
- } );
- }
- return responseBuilder.build();
- }
-}
+++ /dev/null
-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.AuditInformation;
-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.redback.authentication.AuthenticationResult;
-import org.apache.archiva.redback.authorization.AuthorizationException;
-import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal;
-import org.apache.archiva.redback.rest.services.RedbackRequestInformation;
-import org.apache.archiva.redback.system.DefaultSecuritySession;
-import org.apache.archiva.redback.system.SecuritySession;
-import org.apache.archiva.redback.system.SecuritySystem;
-import org.apache.archiva.redback.users.User;
-import org.apache.archiva.redback.users.UserManagerException;
-import org.apache.archiva.redback.users.UserNotFoundException;
-import org.apache.archiva.repository.ManagedRepository;
-import org.apache.archiva.repository.ReleaseScheme;
-import org.apache.archiva.repository.Repository;
-import org.apache.archiva.repository.RepositoryRegistry;
-import org.apache.archiva.repository.RepositoryType;
-import org.apache.archiva.repository.content.ContentItem;
-import org.apache.archiva.repository.content.LayoutException;
-import org.apache.archiva.repository.storage.fs.FsStorageUtil;
-import org.apache.archiva.rest.api.model.v2.FileInfo;
-import org.apache.archiva.rest.api.model.v2.MavenManagedRepository;
-import org.apache.archiva.rest.api.model.v2.MavenManagedRepositoryUpdate;
-import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
-import org.apache.archiva.rest.api.services.v2.ErrorKeys;
-import org.apache.archiva.rest.api.services.v2.ErrorMessage;
-import org.apache.archiva.rest.api.services.v2.maven.MavenManagedRepositoryService;
-import org.apache.archiva.security.common.ArchivaRoleConstants;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.List;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-import static org.apache.archiva.security.common.ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
-import static org.apache.archiva.security.common.ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Service("v2.managedMavenRepositoryService#rest")
-public class DefaultMavenManagedRepositoryService implements MavenManagedRepositoryService
-{
- @Context
- HttpServletResponse httpServletResponse;
-
- @Context
- UriInfo uriInfo;
-
- private static final Logger log = LoggerFactory.getLogger( DefaultMavenManagedRepositoryService.class );
- private static final QueryHelper<ManagedRepository> QUERY_HELPER = new QueryHelper<>( new String[]{"id", "name"} );
- static
- {
- QUERY_HELPER.addStringFilter( "id", ManagedRepository::getId );
- QUERY_HELPER.addStringFilter( "name", ManagedRepository::getName );
- QUERY_HELPER.addStringFilter( "location", (r) -> r.getLocation().toString() );
- QUERY_HELPER.addBooleanFilter( "snapshot", (r) -> r.getActiveReleaseSchemes( ).contains( ReleaseScheme.SNAPSHOT ) );
- QUERY_HELPER.addBooleanFilter( "release", (r) -> r.getActiveReleaseSchemes().contains( ReleaseScheme.RELEASE ));
- QUERY_HELPER.addNullsafeFieldComparator( "id", ManagedRepository::getId );
- QUERY_HELPER.addNullsafeFieldComparator( "name", ManagedRepository::getName );
- }
-
- private ManagedRepositoryAdmin managedRepositoryAdmin;
- private RepositoryRegistry repositoryRegistry;
- private SecuritySystem securitySystem;
-
- public DefaultMavenManagedRepositoryService( SecuritySystem securitySystem,
- RepositoryRegistry repositoryRegistry,
- ManagedRepositoryAdmin managedRepositoryAdmin )
- {
- this.securitySystem = securitySystem;
- this.repositoryRegistry = repositoryRegistry;
- this.managedRepositoryAdmin = managedRepositoryAdmin;
- }
-
- protected AuditInformation getAuditInformation( )
- {
- RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get( );
- User user;
- String remoteAddr;
- if (redbackRequestInformation==null) {
- user = null;
- remoteAddr = null;
- } else
- {
- user = redbackRequestInformation.getUser( );
- remoteAddr = redbackRequestInformation.getRemoteAddr( );
- }
- return new AuditInformation( user, remoteAddr );
- }
-
- @Override
- public PagedResult<MavenManagedRepository> getManagedRepositories( final String searchTerm, final Integer offset,
- final Integer limit, final List<String> orderBy,
- final String order ) throws ArchivaRestServiceException
- {
- try
- {
- Collection<ManagedRepository> repos = repositoryRegistry.getManagedRepositories( );
- final Predicate<ManagedRepository> queryFilter = QUERY_HELPER.getQueryFilter( searchTerm ).and( r -> r.getType() == RepositoryType.MAVEN );
- final Comparator<ManagedRepository> comparator = QUERY_HELPER.getComparator( orderBy, order );
- int totalCount = Math.toIntExact( repos.stream( ).filter( queryFilter ).count( ) );
- return PagedResult.of( totalCount, offset, limit, repos.stream( ).filter( queryFilter ).sorted( comparator )
- .map(mr -> MavenManagedRepository.of(mr)).skip( offset ).limit( limit ).collect( Collectors.toList( ) ) );
- }
- catch (ArithmeticException e) {
- log.error( "Invalid number of repositories detected." );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.INVALID_RESULT_SET_ERROR ) );
- }
- }
-
- @Override
- public MavenManagedRepository getManagedRepository( String repositoryId ) throws ArchivaRestServiceException
- {
- ManagedRepository repo = repositoryRegistry.getManagedRepository( repositoryId );
- if (repo==null) {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryId ), 404 );
- }
- if (repo.getType()!=RepositoryType.MAVEN) {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_WRONG_TYPE, repositoryId, repo.getType().name() ), 404 );
- }
- return MavenManagedRepository.of( repo );
- }
-
- @Override
- public Response deleteManagedRepository( String repositoryId, boolean deleteContent ) throws ArchivaRestServiceException
- {
- ManagedRepository repo = repositoryRegistry.getManagedRepository( repositoryId );
- if (repo==null) {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryId ), 404 );
- }
- if (repo.getType()!=RepositoryType.MAVEN) {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_WRONG_TYPE, repositoryId, repo.getType().name() ), 404 );
- }
- try
- {
- managedRepositoryAdmin.deleteManagedRepository( repositoryId, getAuditInformation( ), deleteContent );
- return Response.ok( ).build( );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_DELETE_FAILED, e.getMessage( ) ) );
- }
- }
-
- private org.apache.archiva.admin.model.beans.ManagedRepository convert(MavenManagedRepository repository) {
- org.apache.archiva.admin.model.beans.ManagedRepository repoBean = new org.apache.archiva.admin.model.beans.ManagedRepository( );
- repoBean.setId( repository.getId( ) );
- repoBean.setName( repository.getName() );
- repoBean.setDescription( repository.getDescription() );
- repoBean.setBlockRedeployments( repository.isBlocksRedeployments() );
- repoBean.setCronExpression( repository.getSchedulingDefinition() );
- repoBean.setLocation( repository.getLocation() );
- repoBean.setReleases( repository.getReleaseSchemes().contains( ReleaseScheme.RELEASE.name() ) );
- repoBean.setSnapshots( repository.getReleaseSchemes().contains( ReleaseScheme.SNAPSHOT.name() ) );
- repoBean.setScanned( repository.isScanned() );
- repoBean.setDeleteReleasedSnapshots( repository.isDeleteSnapshotsOfRelease() );
- repoBean.setSkipPackedIndexCreation( repository.isSkipPackedIndexCreation() );
- repoBean.setRetentionCount( repository.getRetentionCount() );
- repoBean.setRetentionPeriod( repository.getRetentionPeriod().getDays() );
- repoBean.setIndexDirectory( repository.getIndexPath() );
- repoBean.setPackedIndexDirectory( repository.getPackedIndexPath() );
- repoBean.setLayout( repository.getLayout() );
- repoBean.setType( RepositoryType.MAVEN.name( ) );
- return repoBean;
- }
-
- @Override
- public MavenManagedRepository addManagedRepository( MavenManagedRepository managedRepository ) throws ArchivaRestServiceException
- {
- final String repoId = managedRepository.getId( );
- if ( StringUtils.isEmpty( repoId ) ) {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_INVALID_ID, repoId ), 422 );
- }
- Repository repo = repositoryRegistry.getRepository( repoId );
- if (repo!=null) {
- httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder( ).path( repoId ).build( ).toString( ) );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ID_EXISTS, repoId ), 303 );
- }
- try
- {
- managedRepositoryAdmin.addManagedRepository( convert( managedRepository ), managedRepository.isHasStagingRepository(), getAuditInformation() );
- httpServletResponse.setStatus( 201 );
- return MavenManagedRepository.of( repositoryRegistry.getManagedRepository( repoId ) );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
- }
- }
-
- @Override
- public MavenManagedRepository updateManagedRepository( final String repositoryId, final MavenManagedRepositoryUpdate managedRepository ) throws ArchivaRestServiceException
- {
- org.apache.archiva.admin.model.beans.ManagedRepository repo = convert( managedRepository );
- try
- {
- managedRepositoryAdmin.updateManagedRepository( repo, managedRepository.isHasStagingRepository( ), getAuditInformation( ), managedRepository.isResetStats( ) );
- ManagedRepository newRepo = repositoryRegistry.getManagedRepository( managedRepository.getId( ) );
- if (newRepo==null) {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_UPDATE_FAILED, repositoryId ) );
- }
- return MavenManagedRepository.of( newRepo );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
- }
- }
-
- @Override
- public FileInfo getFileStatus( String repositoryId, String fileLocation ) throws ArchivaRestServiceException
- {
- ManagedRepository repo = repositoryRegistry.getManagedRepository( repositoryId );
- if (repo==null) {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryId ), 404 );
- }
- try
- {
- ContentItem contentItem = repo.getContent( ).toItem( fileLocation );
- if (contentItem.getAsset( ).exists( )) {
- return FileInfo.of( contentItem.getAsset( ) );
- } else {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.ARTIFACT_NOT_FOUND, repositoryId, fileLocation ), 404 );
- }
- }
- catch ( LayoutException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_LAYOUT_ERROR, e.getMessage( ) ) );
- }
- }
-
- @Override
- public Response copyArtifact( String srcRepositoryId, String dstRepositoryId,
- String path ) throws ArchivaRestServiceException
- {
- final AuditInformation auditInformation = getAuditInformation( );
- final String userName = auditInformation.getUser( ).getUsername( );
- if ( StringUtils.isEmpty( userName ) )
- {
- httpServletResponse.setHeader( "WWW-Authenticate", "Bearer realm=\"archiva\"" );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.NOT_AUTHENTICATED ), 401 );
- }
- ManagedRepository srcRepo = repositoryRegistry.getManagedRepository( srcRepositoryId );
- if (srcRepo==null) {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, srcRepositoryId ), 404 );
- }
- ManagedRepository dstRepo = repositoryRegistry.getManagedRepository( dstRepositoryId );
- if (dstRepo==null) {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, dstRepositoryId ), 404 );
- }
- checkAuthority( auditInformation.getUser().getUsername(), srcRepositoryId, dstRepositoryId );
- try
- {
- ContentItem srcItem = srcRepo.getContent( ).toItem( path );
- ContentItem dstItem = dstRepo.getContent( ).toItem( path );
- if (!srcItem.getAsset().exists()){
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.ARTIFACT_NOT_FOUND, srcRepositoryId, path ), 404 );
- }
- if (dstItem.getAsset().exists()) {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.ARTIFACT_EXISTS_AT_DEST, srcRepositoryId, path ), 400 );
- }
- FsStorageUtil.copyAsset( srcItem.getAsset( ), dstItem.getAsset( ), true );
- }
- catch ( LayoutException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_LAYOUT_ERROR, e.getMessage() ) );
- }
- catch ( IOException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.ARTIFACT_COPY_ERROR, e.getMessage() ) );
- }
- return Response.ok( ).build();
- }
-
- private void checkAuthority(final String userName, final String srcRepositoryId, final String dstRepositoryId ) throws ArchivaRestServiceException {
- User user = null;
- try
- {
- user = securitySystem.getUserManager().findUser( userName );
- }
- catch ( UserNotFoundException e )
- {
- httpServletResponse.setHeader( "WWW-Authenticate", "Bearer realm=\"archiva\"" );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.USER_NOT_FOUND, userName ), 401 );
- }
- catch ( UserManagerException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.USER_MANAGER_ERROR, e.getMessage( ) ) );
- }
-
- // check karma on source : read
- AuthenticationResult authn = new AuthenticationResult( true, userName, null );
- SecuritySession securitySession = new DefaultSecuritySession( authn, user );
- try
- {
- boolean authz =
- securitySystem.isAuthorized( securitySession, OPERATION_REPOSITORY_ACCESS,
- srcRepositoryId );
- if ( !authz )
- {
- throw new ArchivaRestServiceException(ErrorMessage.of( ErrorKeys.PERMISSION_REPOSITORY_DENIED, srcRepositoryId, OPERATION_REPOSITORY_ACCESS ), 403);
- }
- }
- catch ( AuthorizationException e )
- {
- log.error( "Error reading permission: {}", e.getMessage(), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.AUTHORIZATION_ERROR, e.getMessage() ), 403);
- }
-
- // check karma on target: write
- try
- {
- boolean authz =
- securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD,
- dstRepositoryId );
- if ( !authz )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PERMISSION_REPOSITORY_DENIED, dstRepositoryId, OPERATION_REPOSITORY_UPLOAD ) );
- }
- }
- catch ( AuthorizationException e )
- {
- log.error( "Error reading permission: {}", e.getMessage(), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.AUTHORIZATION_ERROR, e.getMessage() ), 403);
- }
-
-
- }
-
- @Override
- public Response deleteArtifact( String repositoryId, String path ) 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;
- }
-
-}
+++ /dev/null
-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.
- */
-
-/*
- * 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.configuration.RepositoryGroupConfiguration;
-import org.apache.archiva.repository.EditableRepositoryGroup;
-import org.apache.archiva.repository.RepositoryException;
-import org.apache.archiva.repository.RepositoryRegistry;
-import org.apache.archiva.repository.base.ConfigurationHandler;
-import org.apache.archiva.repository.validation.CheckedResult;
-import org.apache.archiva.repository.validation.ValidationError;
-import org.apache.archiva.rest.api.model.v2.MergeConfiguration;
-import org.apache.archiva.rest.api.model.v2.RepositoryGroup;
-import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
-import org.apache.archiva.rest.api.services.v2.ErrorKeys;
-import org.apache.archiva.rest.api.services.v2.ErrorMessage;
-import org.apache.archiva.rest.api.services.v2.RepositoryGroupService;
-import org.apache.archiva.rest.api.services.v2.ValidationException;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-/**
- * REST V2 Implementation for repository groups.
- *
- * @author Martin Stockhammer <martin_s@apache.org>
- * @see RepositoryGroupService
- * @since 3.0
- */
-@Service( "v2.repositoryGroupService#rest" )
-public class DefaultRepositoryGroupService implements RepositoryGroupService
-{
- private final ConfigurationHandler configurationHandler;
-
- @Context
- HttpServletResponse httpServletResponse;
-
- @Context
- UriInfo uriInfo;
-
- final private RepositoryRegistry repositoryRegistry;
-
-
- private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryGroupService.class );
- private static final QueryHelper<org.apache.archiva.repository.RepositoryGroup> QUERY_HELPER = new QueryHelper<>( new String[]{"id"} );
-
- static
- {
- QUERY_HELPER.addStringFilter( "id", org.apache.archiva.repository.RepositoryGroup::getId );
- QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.repository.RepositoryGroup::getId );
- }
-
-
- public DefaultRepositoryGroupService( RepositoryRegistry repositoryRegistry, ConfigurationHandler configurationHandler )
- {
- this.repositoryRegistry = repositoryRegistry;
- this.configurationHandler = configurationHandler;
- }
-
- @Override
- public PagedResult<RepositoryGroup> getRepositoriesGroups( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws ArchivaRestServiceException
- {
- try
- {
- Predicate<org.apache.archiva.repository.RepositoryGroup> filter = QUERY_HELPER.getQueryFilter( searchTerm );
- Comparator<org.apache.archiva.repository.RepositoryGroup> ordering = QUERY_HELPER.getComparator( orderBy, QUERY_HELPER.isAscending( order ) );
- int totalCount = Math.toIntExact( repositoryRegistry.getRepositoryGroups( ).stream( ).filter( filter ).count( ) );
- List<RepositoryGroup> result = repositoryRegistry.getRepositoryGroups( ).stream( ).filter( filter ).sorted( ordering ).skip( offset ).limit( limit ).map(
- RepositoryGroup::of
- ).collect( Collectors.toList( ) );
- return new PagedResult<>( totalCount, offset, limit, result );
- }
- catch ( ArithmeticException e )
- {
- log.error( "Could not convert total count: {}", e.getMessage( ) );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.INVALID_RESULT_SET_ERROR ) );
- }
-
- }
-
- @Override
- public RepositoryGroup getRepositoryGroup( String repositoryGroupId ) throws ArchivaRestServiceException
- {
- if ( StringUtils.isEmpty( repositoryGroupId ) )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
- }
- org.apache.archiva.repository.RepositoryGroup group = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
- return RepositoryGroup.of( group );
- }
-
- private RepositoryGroupConfiguration toConfig( RepositoryGroup group )
- {
- RepositoryGroupConfiguration result = new RepositoryGroupConfiguration( );
- result.setId( group.getId( ) );
- result.setName( group.getName() );
- result.setLocation( group.getLocation( ) );
- result.setRepositories( group.getRepositories( ) );
- MergeConfiguration mergeConfig = group.getMergeConfiguration( );
- if ( mergeConfig != null )
- {
- result.setMergedIndexPath( mergeConfig.getMergedIndexPath( ) );
- result.setMergedIndexTtl( mergeConfig.getMergedIndexTtlMinutes( ) );
- result.setCronExpression( mergeConfig.getIndexMergeSchedule( ) );
- }
- return result;
- }
-
- @Override
- public RepositoryGroup addRepositoryGroup( RepositoryGroup repositoryGroup ) throws ArchivaRestServiceException
- {
- final String groupId = repositoryGroup.getId( );
- if ( StringUtils.isEmpty( groupId ) )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_INVALID_ID, groupId ), 422 );
- }
- if ( repositoryRegistry.hasRepositoryGroup( groupId ) )
- {
- httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder( ).path( groupId ).build( ).toString( ) );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ID_EXISTS, groupId ), 303 );
- }
- try
- {
-
- RepositoryGroupConfiguration configuration = toConfig( repositoryGroup );
- CheckedResult<org.apache.archiva.repository.RepositoryGroup, Map<String, List<ValidationError>>> validationResult = repositoryRegistry.putRepositoryGroupAndValidate( configuration );
- if ( validationResult.isValid( ) )
- {
- httpServletResponse.setStatus( 201 );
- return RepositoryGroup.of( validationResult.getRepository( ) );
- }
- else
- {
- throw ValidationException.of( validationResult.getResult( ) );
- }
- }
- catch ( RepositoryException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_ADD_FAILED ) );
- }
- }
-
- @Override
- public RepositoryGroup updateRepositoryGroup( final String repositoryGroupId, final RepositoryGroup repositoryGroup ) throws ArchivaRestServiceException
- {
- if ( StringUtils.isEmpty( repositoryGroupId ) )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
- }
- if ( !repositoryRegistry.hasRepositoryGroup( repositoryGroupId ) )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND ), 404 );
- }
- repositoryGroup.setId( repositoryGroupId );
- try
- {
- RepositoryGroupConfiguration configuration = toConfig( repositoryGroup );
- CheckedResult<org.apache.archiva.repository.RepositoryGroup, Map<String, List<ValidationError>>> validationResult = repositoryRegistry.putRepositoryGroupAndValidate( configuration );
- if ( validationResult.isValid( ) )
- {
- httpServletResponse.setStatus( 201 );
- return RepositoryGroup.of( validationResult.getRepository( ) );
- }
- else
- {
- throw ValidationException.of( validationResult.getResult( ) );
- }
- }
- catch ( RepositoryException e )
- {
- log.error( "Exception during repository group update: {}", e.getMessage( ), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage( ) ) );
-
- }
- }
-
- @Override
- public Response deleteRepositoryGroup( String repositoryGroupId ) throws ArchivaRestServiceException
- {
- if ( StringUtils.isEmpty( repositoryGroupId ) )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
- }
- try
- {
- org.apache.archiva.repository.RepositoryGroup group = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
- if ( group == null )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
- }
- repositoryRegistry.removeRepositoryGroup( group );
- return Response.ok( ).build( );
- }
- catch ( RepositoryException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_DELETE_FAILED ) );
- }
- }
-
- @Override
- public RepositoryGroup addRepositoryToGroup( String repositoryGroupId, String repositoryId ) throws ArchivaRestServiceException
- {
- if ( StringUtils.isEmpty( repositoryGroupId ) )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
- }
- if ( StringUtils.isEmpty( repositoryId ) )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
- }
- try
- {
- org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
- if ( repositoryGroup == null )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
- }
- if ( !( repositoryGroup instanceof EditableRepositoryGroup ) )
- {
- log.error( "This group instance is not editable: {}", repositoryGroupId );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, "" ), 500 );
- }
- EditableRepositoryGroup editableRepositoryGroup = (EditableRepositoryGroup) repositoryGroup;
- if ( editableRepositoryGroup.getRepositories( ).stream( ).anyMatch( repo -> repositoryId.equals( repo.getId( ) ) ) )
- {
- log.info( "Repository {} is already member of group {}", repositoryId, repositoryGroupId );
- return RepositoryGroup.of( editableRepositoryGroup );
- }
- org.apache.archiva.repository.ManagedRepository managedRepo = repositoryRegistry.getManagedRepository( repositoryId );
- if ( managedRepo == null )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
- }
- editableRepositoryGroup.addRepository( managedRepo );
- org.apache.archiva.repository.RepositoryGroup newGroup = repositoryRegistry.putRepositoryGroup( editableRepositoryGroup );
- return RepositoryGroup.of( newGroup );
- }
- catch ( RepositoryException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage( ) ), 500 );
- }
- }
-
- @Override
- public RepositoryGroup deleteRepositoryFromGroup( final String repositoryGroupId, final String repositoryId ) throws org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException
- {
- if ( StringUtils.isEmpty( repositoryGroupId ) )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, repositoryGroupId ), 404 );
- }
- if ( StringUtils.isEmpty( repositoryId ) )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryId ), 404 );
- }
- try
- {
- org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
- if ( repositoryGroup == null )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
- }
- if ( repositoryGroup.getRepositories( ).stream( ).noneMatch( r -> repositoryId.equals( r.getId( ) ) ) )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryId ), 404 );
- }
- if ( !( repositoryGroup instanceof EditableRepositoryGroup ) )
- {
- log.error( "This group instance is not editable: {}", repositoryGroupId );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, "" ), 500 );
- }
- EditableRepositoryGroup editableRepositoryGroup = (EditableRepositoryGroup) repositoryGroup;
- editableRepositoryGroup.removeRepository( repositoryId );
- org.apache.archiva.repository.RepositoryGroup newGroup = repositoryRegistry.putRepositoryGroup( editableRepositoryGroup );
- return RepositoryGroup.of( newGroup );
- }
- catch ( RepositoryException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage( ) ), 500 );
- }
- }
-
-
-}
+++ /dev/null
-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.admin.RepositoryTaskAdministration;
-import org.apache.archiva.components.rest.model.PagedResult;
-import org.apache.archiva.components.rest.util.QueryHelper;
-import org.apache.archiva.components.rest.util.RestUtil;
-import org.apache.archiva.metadata.repository.MetadataRepositoryException;
-import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
-import org.apache.archiva.repository.RemoteRepository;
-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.Repository;
-import org.apache.archiva.rest.api.model.v2.RepositoryStatistics;
-import org.apache.archiva.rest.api.model.v2.ScanStatus;
-import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
-import org.apache.archiva.rest.api.services.v2.ErrorKeys;
-import org.apache.archiva.rest.api.services.v2.ErrorMessage;
-import org.apache.archiva.rest.api.services.v2.RepositoryService;
-import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexException;
-import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexScheduler;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-
-import javax.inject.Named;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Locale;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-@Service( "v2.repositoryService#rest" )
-public class DefaultRepositoryService implements RepositoryService
-{
-
- final
- RepositoryRegistry repositoryRegistry;
-
- final
- RepositoryStatisticsManager repositoryStatisticsManager;
-
- private final RepositoryTaskAdministration repositoryTaskAdministration;
-
- private final RepositoryScanner repoScanner;
-
- private final DownloadRemoteIndexScheduler downloadRemoteIndexScheduler;
-
- private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryService.class );
- private static final QueryHelper<org.apache.archiva.repository.Repository> QUERY_HELPER = new QueryHelper<>( new String[]{"id", "name"} );
-
- static
- {
- QUERY_HELPER.addStringFilter( "id", org.apache.archiva.repository.Repository::getId );
- QUERY_HELPER.addStringFilter( "name", org.apache.archiva.repository.Repository::getName );
- QUERY_HELPER.addStringFilter( "description", org.apache.archiva.repository.Repository::getDescription );
- QUERY_HELPER.addStringFilter( "type", repo -> repo.getType( ).name( ) );
- QUERY_HELPER.addBooleanFilter( "scanned", org.apache.archiva.repository.Repository::isScanned );
- QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.repository.Repository::getId );
- QUERY_HELPER.addNullsafeFieldComparator( "name", org.apache.archiva.repository.Repository::getName );
- QUERY_HELPER.addNullsafeFieldComparator( "type", repo -> repo.getType( ).name( ) );
- QUERY_HELPER.addNullsafeFieldComparator( "boolean", org.apache.archiva.repository.Repository::isScanned );
- }
-
- public DefaultRepositoryService( RepositoryRegistry repositoryRegistry, RepositoryStatisticsManager repositoryStatisticsManager,
- @Named( value = "repositoryTaskAdministration#default") RepositoryTaskAdministration repositoryTaskAdministration,
- RepositoryScanner repoScanner, DownloadRemoteIndexScheduler downloadRemoteIndexScheduler )
- {
- this.repositoryRegistry = repositoryRegistry;
- this.repositoryStatisticsManager = repositoryStatisticsManager;
- this.repoScanner = repoScanner;
- this.repositoryTaskAdministration = repositoryTaskAdministration;
- this.downloadRemoteIndexScheduler = downloadRemoteIndexScheduler;
- }
-
- private void handleAdminException( RepositoryAdminException e ) throws ArchivaRestServiceException
- {
- log.error( "Repository admin error: {}", e.getMessage( ), e );
- if ( e.keyExists( ) )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PREFIX + e.getKey( ), e.getParameters( ) ) );
- }
- else
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
- }
- }
-
-
- @Override
- public PagedResult<Repository> getRepositories( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order,
- String localeString ) throws ArchivaRestServiceException
- {
- final Locale locale = StringUtils.isNotEmpty( localeString ) ? Locale.forLanguageTag( localeString ) : Locale.getDefault( );
- boolean isAscending = QUERY_HELPER.isAscending( order );
- Predicate<org.apache.archiva.repository.Repository> filter = QUERY_HELPER.getQueryFilter( searchTerm );
- Comparator<org.apache.archiva.repository.Repository> comparator = QUERY_HELPER.getComparator( orderBy, isAscending );
- try
- {
- int totalCount = Math.toIntExact( repositoryRegistry.getRepositories( ).stream( ).filter( filter ).count( ) );
- return new PagedResult<>( totalCount, offset, limit, repositoryRegistry.getRepositories( ).stream( )
- .filter( filter ).skip( offset ).limit( limit ).sorted( comparator ).map( repo -> Repository.of( repo, locale ) )
- .collect( Collectors.toList( ) ) );
- }
- catch ( ArithmeticException e )
- {
- log.error( "Invalid integer conversion for totalCount" );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.INVALID_RESULT_SET_ERROR ) );
- }
- }
-
- @Override
- public RepositoryStatistics getManagedRepositoryStatistics( String repositoryId ) throws ArchivaRestServiceException
- {
- if ( repositoryRegistry.getManagedRepository( repositoryId ) == null )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_MANAGED_NOT_FOUND, repositoryId ), 404 );
- }
- try
- {
- return RepositoryStatistics.of( repositoryStatisticsManager.getLastStatistics( repositoryId ) );
- }
- catch ( MetadataRepositoryException e )
- {
- log.error( "Metadata error: {} ", e.getMessage( ), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_METADATA_ERROR, e.getMessage( ) ) );
- }
- }
-
- @Override
- public Response scheduleRepositoryScan( String repositoryId, boolean fullScan ) throws ArchivaRestServiceException
- {
- try
- {
- repositoryTaskAdministration.scheduleFullScan( repositoryId );
- return Response.ok( ).build( );
- }
- catch ( RepositoryAdminException e )
- {
- handleAdminException( e );
- return Response.serverError( ).build( );
- }
- }
-
- @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
- {
- try
- {
- return ScanStatus.of( repositoryTaskAdministration.getCurrentScanStatus( ) );
- }
- catch ( RepositoryAdminException e )
- {
- handleAdminException( e );
- return new ScanStatus();
- }
- }
-
- @Override
- public Response removeScanningTaskFromQueue( String repositoryId ) throws ArchivaRestServiceException
- {
- try
- {
- repositoryTaskAdministration.cancelTasks( repositoryId );
- return Response.ok( ).build( );
- }
- catch ( RepositoryAdminException e )
- {
- handleAdminException( e );
- return Response.serverError( ).build( );
- }
- }
-
-
- @Override
- public Response scheduleDownloadRemoteIndex( String repositoryId, boolean immediately, boolean full,
- UriInfo uriInfo ) throws ArchivaRestServiceException
- {
- boolean immediateSet = RestUtil.isFlagSet( uriInfo, "immediate" );
- boolean fullSet = RestUtil.isFlagSet( uriInfo, "full" );
- RemoteRepository repo = repositoryRegistry.getRemoteRepository( repositoryId );
- if (repo==null) {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_REMOTE_NOT_FOUND, repositoryId ), 404 );
- }
- try
- {
- downloadRemoteIndexScheduler.scheduleDownloadRemote( repositoryId, immediateSet, fullSet );
- return Response.ok( ).build( );
- }
- catch ( DownloadRemoteIndexException e )
- {
- log.error( "Could not schedule index download for repository {}: {}", repositoryId, e.getMessage(), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_REMOTE_INDEX_DOWNLOAD_FAILED, e.getMessage( ) ) );
- }
- }
-
-
-
- @Override
- public List<String> getRunningRemoteDownloads( )
- {
- return downloadRemoteIndexScheduler.getRunningRemoteDownloadIds( );
- }
-}
+++ /dev/null
-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.
- */
-
-/*
- * 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;
-import org.apache.archiva.components.rest.model.PagedResult;
-import org.apache.archiva.components.rest.model.PropertyEntry;
-import org.apache.archiva.components.rest.util.QueryHelper;
-import org.apache.archiva.redback.authentication.Authenticator;
-import org.apache.archiva.redback.common.ldap.connection.LdapConnection;
-import org.apache.archiva.redback.common.ldap.connection.LdapConnectionConfiguration;
-import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory;
-import org.apache.archiva.redback.common.ldap.connection.LdapException;
-import org.apache.archiva.redback.common.ldap.user.LdapUserMapper;
-import org.apache.archiva.redback.policy.CookieSettings;
-import org.apache.archiva.redback.policy.PasswordRule;
-import org.apache.archiva.redback.rbac.RBACManager;
-import org.apache.archiva.redback.role.RoleManager;
-import org.apache.archiva.redback.users.UserManager;
-import org.apache.archiva.rest.api.model.v2.BeanInformation;
-import org.apache.archiva.rest.api.model.v2.CacheConfiguration;
-import org.apache.archiva.rest.api.model.v2.LdapConfiguration;
-import org.apache.archiva.rest.api.model.v2.SecurityConfiguration;
-import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
-import org.apache.archiva.rest.api.services.v2.ErrorKeys;
-import org.apache.archiva.rest.api.services.v2.ErrorMessage;
-import org.apache.archiva.rest.api.services.v2.SecurityConfigurationService;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.naming.AuthenticationException;
-import javax.naming.AuthenticationNotSupportedException;
-import javax.naming.CommunicationException;
-import javax.naming.InvalidNameException;
-import javax.naming.NamingException;
-import javax.naming.NoPermissionException;
-import javax.naming.ServiceUnavailableException;
-import javax.ws.rs.core.Response;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.ResourceBundle;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-import static org.apache.archiva.rest.api.services.v2.ErrorKeys.INVALID_RESULT_SET_ERROR;
-import static org.apache.archiva.rest.api.services.v2.ErrorKeys.REPOSITORY_ADMIN_ERROR;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Service( "v2.defaultSecurityConfigurationService" )
-public class DefaultSecurityConfigurationService implements SecurityConfigurationService
-{
- private static final Logger log = LoggerFactory.getLogger( DefaultSecurityConfigurationService.class );
-
- private static final String[] KNOWN_LDAP_CONTEXT_PROVIDERS = {"com.sun.jndi.ldap.LdapCtxFactory","com.ibm.jndi.LDAPCtxFactory"};
- private final List<String> availableContextProviders = new ArrayList<>( );
-
- private static final QueryHelper<PropertyEntry> PROP_QUERY_HELPER = new QueryHelper<>( new String[]{"key"} );
-
- static
- {
- PROP_QUERY_HELPER.addStringFilter( "key", PropertyEntry::getKey );
- PROP_QUERY_HELPER.addStringFilter( "value", PropertyEntry::getValue );
- PROP_QUERY_HELPER.addNullsafeFieldComparator( "key", PropertyEntry::getKey );
- PROP_QUERY_HELPER.addNullsafeFieldComparator( "value", PropertyEntry::getValue );
-
- }
-
- private ResourceBundle bundle;
-
-
- @Inject
- private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin;
-
- @Inject
- private ApplicationContext applicationContext;
-
- @Inject
- @Named( value = "userManager#default" )
- private UserManager userManager;
-
- @Inject
- @Named( value = "rbacManager#default" )
- private RBACManager rbacManager;
-
- @Inject
- private RoleManager roleManager;
-
- @Inject
- @Named( value = "ldapConnectionFactory#configurable" )
- private LdapConnectionFactory ldapConnectionFactory;
-
- @Inject
- private LdapUserMapper ldapUserMapper;
-
-
- @PostConstruct
- void init( )
- {
- bundle = ResourceBundle.getBundle( "org.apache.archiva.rest.RestBundle" );
- for (String ldapClass : KNOWN_LDAP_CONTEXT_PROVIDERS) {
- if (isContextFactoryAvailable( ldapClass )) {
- availableContextProviders.add( ldapClass );
- }
- }
- }
-
- @Override
- public SecurityConfiguration getConfiguration( ) throws ArchivaRestServiceException
- {
- try
- {
- RedbackRuntimeConfiguration redbackRuntimeConfiguration =
- redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
-
- log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
-
- return SecurityConfiguration.ofRedbackConfiguration( redbackRuntimeConfiguration );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
- }
- }
-
- private void updateConfig( SecurityConfiguration newConfig, RedbackRuntimeConfiguration rbConfig )
- {
- rbConfig.setUserManagerImpls( newConfig.getActiveUserManagers( ) );
- rbConfig.setRbacManagerImpls( newConfig.getActiveRbacManagers( ) );
- rbConfig.setUseUsersCache( newConfig.isUserCacheEnabled( ) );
- Map<String, String> props = rbConfig.getConfigurationProperties( );
- for ( Map.Entry<String, String> newProp : newConfig.getProperties( ).entrySet( ) )
- {
- props.put( newProp.getKey( ), newProp.getValue( ) );
- }
- }
-
- private void updateConfig( LdapConfiguration newConfig, RedbackRuntimeConfiguration rbConfig )
- {
- org.apache.archiva.admin.model.beans.LdapConfiguration ldapConfig = rbConfig.getLdapConfiguration( );
- ldapConfig.setBaseDn( newConfig.getBaseDn( ) );
- ldapConfig.setAuthenticationMethod( newConfig.getAuthenticationMethod( ) );
- ldapConfig.setBindAuthenticatorEnabled( newConfig.isBindAuthenticatorEnabled( ) );
- ldapConfig.setBindDn( newConfig.getBindDn( ) );
- ldapConfig.setSsl( newConfig.isSslEnabled( ) );
- ldapConfig.setBaseGroupsDn( newConfig.getGroupsBaseDn( ) );
- ldapConfig.setHostName( newConfig.getHostName( ) );
- ldapConfig.setPort( newConfig.getPort( ) );
- ldapConfig.setPassword( newConfig.getBindPassword( ) );
- ldapConfig.setUseRoleNameAsGroup( newConfig.isUseRoleNameAsGroup( ) );
- ldapConfig.setWritable( newConfig.isWritable( ) );
- ldapConfig.setContextFactory( newConfig.getContextFactory( ) );
-
- Map<String, String> props = ldapConfig.getExtraProperties( );
- for ( Map.Entry<String, String> newProp : newConfig.getProperties( ).entrySet( ) )
- {
- props.put( newProp.getKey( ), newProp.getValue( ) );
- }
- }
-
- private void updateConfig( CacheConfiguration newConfig, RedbackRuntimeConfiguration rbConfig )
- {
- org.apache.archiva.admin.model.beans.CacheConfiguration cacheConfig = rbConfig.getUsersCacheConfiguration( );
- cacheConfig.setMaxElementsInMemory( newConfig.getMaxEntriesInMemory( ) );
- cacheConfig.setMaxElementsOnDisk( newConfig.getMaxEntriesOnDisk( ) );
- cacheConfig.setTimeToLiveSeconds( newConfig.getTimeToLiveSeconds( ) );
- cacheConfig.setTimeToIdleSeconds( newConfig.getTimeToIdleSeconds( ) );
- }
-
- @Override
- public SecurityConfiguration updateConfiguration( SecurityConfiguration newConfiguration ) throws ArchivaRestServiceException
- {
- if ( newConfiguration == null )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.MISSING_DATA ), 400 );
- }
- try
- {
- RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
- boolean userManagerChanged = !CollectionUtils.isEqualCollection( newConfiguration.getActiveUserManagers( ), conf.getUserManagerImpls( ) );
- boolean rbacManagerChanged = !CollectionUtils.isEqualCollection( newConfiguration.getActiveRbacManagers( ), conf.getRbacManagerImpls( ) );
-
- boolean ldapConfigured = newConfiguration.getActiveUserManagers( ).stream( ).anyMatch( um -> um.contains( "ldap" ) );
- if ( !ldapConfigured )
- {
- ldapConfigured= newConfiguration.getActiveRbacManagers( ).stream( ).anyMatch( um -> um.contains( "ldap" ) );
- }
-
- updateConfig( newConfiguration, conf );
- redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( conf );
-
- if ( userManagerChanged )
- {
- log.info( "user managerImpls changed to {} so reload it",
- newConfiguration.getActiveUserManagers( ) );
- userManager.initialize( );
- }
-
- if ( rbacManagerChanged )
- {
- log.info( "rbac manager changed to {} so reload it",
- newConfiguration.getActiveRbacManagers( ) );
- rbacManager.initialize( );
- roleManager.initialize( );
- }
-
- if ( ldapConfigured )
- {
- try
- {
- ldapConnectionFactory.initialize( );
- }
- catch ( Exception e )
- {
- log.error( "Could not initialize LDAP connection factory: {}", e.getMessage( ) );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_CF_INIT_FAILED, e.getMessage( ) ) );
- }
- }
- Collection<PasswordRule> passwordRules = applicationContext.getBeansOfType( PasswordRule.class ).values( );
-
- for ( PasswordRule passwordRule : passwordRules )
- {
- passwordRule.initialize( );
- }
-
- Collection<CookieSettings> cookieSettingsList =
- applicationContext.getBeansOfType( CookieSettings.class ).values( );
-
- for ( CookieSettings cookieSettings : cookieSettingsList )
- {
- cookieSettings.initialize( );
- }
-
- Collection<Authenticator> authenticators =
- applicationContext.getBeansOfType( Authenticator.class ).values( );
-
- for ( Authenticator authenticator : authenticators )
- {
- try
- {
- log.debug( "Initializing authenticatior " + authenticator.getId( ) );
- authenticator.initialize( );
- }
- catch ( Exception e )
- {
- log.error( "Initialization of authenticator failed " + authenticator.getId( ), e );
- }
- }
-
- if ( ldapConfigured )
- {
- try
- {
- ldapUserMapper.initialize( );
- }
- catch ( Exception e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_USER_MAPPER_INIT_FAILED, e.getMessage( ) ) );
- }
- }
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
- }
- try
- {
- return SecurityConfiguration.ofRedbackConfiguration( redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( ) );
- }
- catch ( RepositoryAdminException e )
- {
- log.error( "Error while retrieve updated configuration: {}", e.getMessage( ) );
- throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
- }
- }
-
- @Override
- public PagedResult<PropertyEntry> getConfigurationProperties( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws ArchivaRestServiceException
- {
- try
- {
- RedbackRuntimeConfiguration redbackRuntimeConfiguration =
- redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
-
- log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
-
- boolean ascending = PROP_QUERY_HELPER.isAscending( order );
- Predicate<PropertyEntry> filter = PROP_QUERY_HELPER.getQueryFilter( searchTerm );
- Comparator<PropertyEntry> comparator = PROP_QUERY_HELPER.getComparator( orderBy, ascending );
- Map<String, String> props = redbackRuntimeConfiguration.getConfigurationProperties( );
- int totalCount = Math.toIntExact( props.entrySet( ).stream( ).map(
- entry -> new PropertyEntry( entry.getKey( ), entry.getValue( ) )
- ).filter( filter ).count( ) );
- List<PropertyEntry> result = props.entrySet( ).stream( ).map(
- entry -> new PropertyEntry( entry.getKey( ), entry.getValue( ) )
- ).filter( filter )
- .sorted( comparator )
- .skip( offset ).limit( limit )
- .collect( Collectors.toList( ) );
- return new PagedResult<>( totalCount, offset, limit, result );
- } catch (ArithmeticException e) {
- log.error( "The total count of the result properties is higher than max integer value!" );
- throw new ArchivaRestServiceException( ErrorMessage.of( INVALID_RESULT_SET_ERROR ) );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
- }
- }
-
- @Override
- public PropertyEntry getConfigurationProperty( String propertyName ) throws ArchivaRestServiceException
- {
- try
- {
- RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
- if ( conf.getConfigurationProperties( ).containsKey( propertyName ) )
- {
- String value = conf.getConfigurationProperties( ).get( propertyName );
- return new PropertyEntry( propertyName, value );
- }
- else
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PROPERTY_NOT_FOUND ), 404 );
- }
-
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
- }
-
- }
-
- @Override
- public Response updateConfigurationProperty( String propertyName, PropertyEntry propertyValue ) throws ArchivaRestServiceException
- {
- if ( propertyValue == null )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.MISSING_DATA ), 400 );
- }
- try
- {
- RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
- if ( conf.getConfigurationProperties( ).containsKey( propertyName ) )
- {
- conf.getConfigurationProperties( ).put( propertyName, propertyValue.getValue( ) );
- redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( conf );
- return Response.ok( ).build( );
- }
- else
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PROPERTY_NOT_FOUND ), 404 );
- }
-
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
- }
- }
-
- @Override
- public LdapConfiguration getLdapConfiguration( ) throws ArchivaRestServiceException
- {
- try
- {
- RedbackRuntimeConfiguration redbackRuntimeConfiguration =
- redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
-
- log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
-
- LdapConfiguration ldapConfig = LdapConfiguration.of( redbackRuntimeConfiguration.getLdapConfiguration( ) );
- ldapConfig.setAvailableContextFactories( availableContextProviders );
- return ldapConfig;
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
- }
-
- }
-
- @Override
- public LdapConfiguration updateLdapConfiguration( LdapConfiguration configuration ) throws ArchivaRestServiceException
- {
- try
- {
- RedbackRuntimeConfiguration redbackRuntimeConfiguration =
- redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
-
- log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
-
- updateConfig( configuration, redbackRuntimeConfiguration );
-
- redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration );
- ldapConnectionFactory.initialize( );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
- }
-
- try
- {
- return LdapConfiguration.of( redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( ).getLdapConfiguration() );
- }
- catch ( RepositoryAdminException e )
- {
- log.error( "Error while retrieve updated configuration: {}", e.getMessage( ) );
- throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
- }
-
- }
-
- static Properties toProperties( Map<String, String> values )
- {
- Properties result = new Properties( );
- for ( Map.Entry<String, String> entry : values.entrySet( ) )
- {
- result.setProperty( entry.getKey( ), entry.getValue( ) );
- }
- return result;
- }
-
- private static boolean isContextFactoryAvailable( final String factoryClass)
- {
- try
- {
- return Thread.currentThread().getContextClassLoader().loadClass( factoryClass )
- != null;
- }
- catch ( ClassNotFoundException e )
- {
- return false;
- }
- }
-
-
- @Override
- public Response verifyLdapConfiguration( LdapConfiguration ldapConfiguration ) throws ArchivaRestServiceException
- {
- LdapConnection ldapConnection = null;
- try
- {
- LdapConnectionConfiguration ldapConnectionConfiguration =
- new LdapConnectionConfiguration( ldapConfiguration.getHostName( ), ldapConfiguration.getPort( ),
- ldapConfiguration.getBaseDn( ), ldapConfiguration.getContextFactory( ),
- ldapConfiguration.getBindDn( ), ldapConfiguration.getBindPassword( ),
- ldapConfiguration.getAuthenticationMethod( ),
- toProperties( ldapConfiguration.getProperties( ) ) );
- ldapConnectionConfiguration.setSsl( ldapConfiguration.isSslEnabled( ) );
-
- ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration );
- }
- catch ( InvalidNameException e )
- {
- log.warn( "LDAP connection check failed with invalid name : {}", e.getMessage( ), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_INVALID_NAME, e.getMessage( ) ), 400 );
- }
- catch ( LdapException e )
- {
- handleLdapException( e );
- }
- finally
- {
- if ( ldapConnection != null )
- {
- try
- {
- ldapConnection.close( );
- }
- catch ( NamingException e )
- {
- log.error( "Could not close connection: {}", e.getMessage( ) );
- }
- }
- ldapConnection = null;
- }
-
- try
- {
- // verify groups dn value too
-
- LdapConnectionConfiguration ldapConnectionConfiguration = new LdapConnectionConfiguration( ldapConfiguration.getHostName( ), ldapConfiguration.getPort( ),
- ldapConfiguration.getGroupsBaseDn( ),
- ldapConfiguration.getContextFactory( ), ldapConfiguration.getBindDn( ),
- ldapConfiguration.getBindPassword( ),
- ldapConfiguration.getAuthenticationMethod( ),
- toProperties( ldapConfiguration.getProperties( ) ) );
-
- ldapConnectionConfiguration.setSsl( ldapConfiguration.isSslEnabled( ) );
-
- ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration );
- }
- catch ( InvalidNameException e )
- {
- log.warn( "LDAP connection check failed with invalid name : {}", e.getMessage( ), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_INVALID_NAME, e.getMessage( ) ), 400 );
- }
- catch ( LdapException e )
- {
- handleLdapException( e );
- }
- finally
- {
- if ( ldapConnection != null )
- {
- try
- {
- ldapConnection.close( );
- }
- catch ( NamingException e )
- {
- log.error( "Could not close connection: {}", e.getMessage( ), e );
- }
- }
- }
-
- return Response.ok( ).build( );
- }
-
- private void handleLdapException( LdapException e ) throws ArchivaRestServiceException
- {
- Throwable rootCause = e.getRootCause( );
- if ( rootCause instanceof CommunicationException )
- {
- log.warn( "LDAP connection check failed with CommunicationException: {}", e.getMessage( ), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_COMMUNICATION_ERROR, e.getMessage( ) ), 400 );
- } else if (rootCause instanceof ServiceUnavailableException ) {
- log.warn( "LDAP connection check failed with ServiceUnavailableException: {}", e.getMessage( ), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_UNAVAILABLE, e.getMessage( ) ), 400 );
- } else if (rootCause instanceof AuthenticationException ) {
- log.warn( "LDAP connection check failed with AuthenticationException: {}", e.getMessage( ), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_AUTHENTICATION_FAILED, e.getMessage( ) ), 400 );
- } else if (rootCause instanceof AuthenticationNotSupportedException ) {
- log.warn( "LDAP connection check failed with AuthenticationNotSupportedException: {}", e.getMessage( ), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_AUTHENTICATION_NOT_SUPPORTED, e.getMessage( ) ), 400 );
- } else if (rootCause instanceof NoPermissionException ) {
- log.warn( "LDAP connection check failed with NoPermissionException: {}", e.getMessage( ), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_NO_PERMISSION, e.getMessage( ) ), 400 );
- }
- log.warn( "LDAP connection check failed: {} - {}", e.getClass().getName(), e.getMessage( ), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_GENERIC_ERROR, e.getMessage( ) ), 400 );
- }
-
- @Override
- public CacheConfiguration getCacheConfiguration( ) throws ArchivaRestServiceException
- {
- try
- {
- RedbackRuntimeConfiguration redbackRuntimeConfiguration =
- redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
-
- log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
-
- return CacheConfiguration.of( redbackRuntimeConfiguration.getUsersCacheConfiguration( ) );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
- }
-
- }
-
- @Override
- public CacheConfiguration updateCacheConfiguration( CacheConfiguration cacheConfiguration ) throws ArchivaRestServiceException
- {
- if ( cacheConfiguration == null )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.MISSING_DATA ), 400 );
- }
- try
- {
- RedbackRuntimeConfiguration redbackRuntimeConfiguration =
- redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
-
- log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
- updateConfig( cacheConfiguration, redbackRuntimeConfiguration );
- redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration );
- return getCacheConfiguration( );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
- }
- }
-
- @Override
- public List<BeanInformation> getAvailableUserManagers( )
- {
- Map<String, UserManager> beans = applicationContext.getBeansOfType( UserManager.class );
-
- if ( beans.isEmpty( ) )
- {
- return Collections.emptyList( );
- }
-
- return beans.entrySet( ).stream( )
- .filter( entry -> entry.getValue( ).isFinalImplementation( ) )
- .map( ( Map.Entry<String, UserManager> entry ) -> {
- UserManager um = entry.getValue( );
- String id = StringUtils.substringAfter( entry.getKey( ), "#" );
- String displayName = bundle.getString( "user_manager." + id + ".display_name" );
- String description = bundle.getString( "user_manager." + id + ".description" );
- return new BeanInformation( StringUtils.substringAfter( entry.getKey( ), "#" ), displayName, um.getDescriptionKey( ), description, um.isReadOnly( ) );
- } ).collect( Collectors.toList( ) );
- }
-
- @Override
- public List<BeanInformation> getAvailableRbacManagers( )
- {
- Map<String, RBACManager> beans = applicationContext.getBeansOfType( RBACManager.class );
-
- if ( beans.isEmpty( ) )
- {
- return Collections.emptyList( );
- }
-
- return beans.entrySet( ).stream( )
- .filter( entry -> entry.getValue( ).isFinalImplementation( ) )
- .map( ( Map.Entry<String, RBACManager> entry ) -> {
- RBACManager rm = entry.getValue( );
- String id = StringUtils.substringAfter( entry.getKey( ), "#" );
- String displayName = bundle.getString( "rbac_manager." + id + ".display_name" );
- String description = bundle.getString( "rbac_manager." + id + ".description" );
- return new BeanInformation( StringUtils.substringAfter( entry.getKey( ), "#" ), displayName, rm.getDescriptionKey( ), description, rm.isReadOnly( ) );
- } ).collect( Collectors.toList( ) );
- }
-}
--- /dev/null
+package org.apache.archiva.rest.v2.interceptor;
+/*
+ * 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.v2.svc.ArchivaRestError;
+import org.apache.archiva.rest.api.v2.svc.ArchivaRestServiceException;
+import org.springframework.stereotype.Service;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+/**
+ * Maps exceptions to REST responses.
+ *
+ * @author Martin Stockhammer
+ * @since 3.0
+ */
+@Provider
+@Service( "v2.archivaRestServiceExceptionMapper" )
+public class ArchivaRestServiceExceptionMapper
+ implements ExceptionMapper<ArchivaRestServiceException>
+{
+ @Override
+ public Response toResponse( final ArchivaRestServiceException e )
+ {
+ ArchivaRestError restError = new ArchivaRestError( e );
+
+ Response.ResponseBuilder responseBuilder = Response.status( e.getHttpErrorCode() ).entity( restError );
+ if ( e.getMessage() != null )
+ {
+ responseBuilder = responseBuilder.status( new Response.StatusType()
+ {
+ public int getStatusCode()
+ {
+ return e.getHttpErrorCode();
+ }
+
+ public Response.Status.Family getFamily()
+ {
+ return Response.Status.Family.familyOf( e.getHttpErrorCode( ) );
+ }
+
+ public String getReasonPhrase()
+ {
+ return e.getMessage();
+ }
+ } );
+ }
+ return responseBuilder.build();
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.v2.svc;
+/*
+ * 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.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.redback.authentication.AuthenticationResult;
+import org.apache.archiva.redback.authorization.AuthorizationException;
+import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal;
+import org.apache.archiva.redback.rest.services.RedbackRequestInformation;
+import org.apache.archiva.redback.system.DefaultSecuritySession;
+import org.apache.archiva.redback.system.SecuritySession;
+import org.apache.archiva.redback.system.SecuritySystem;
+import org.apache.archiva.redback.users.User;
+import org.apache.archiva.redback.users.UserManagerException;
+import org.apache.archiva.redback.users.UserNotFoundException;
+import org.apache.archiva.repository.ManagedRepository;
+import org.apache.archiva.repository.ReleaseScheme;
+import org.apache.archiva.repository.Repository;
+import org.apache.archiva.repository.RepositoryRegistry;
+import org.apache.archiva.repository.RepositoryType;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.LayoutException;
+import org.apache.archiva.repository.storage.fs.FsStorageUtil;
+import org.apache.archiva.rest.api.v2.model.FileInfo;
+import org.apache.archiva.rest.api.v2.model.MavenManagedRepository;
+import org.apache.archiva.rest.api.v2.model.MavenManagedRepositoryUpdate;
+import org.apache.archiva.rest.api.v2.svc.ArchivaRestServiceException;
+import org.apache.archiva.rest.api.v2.svc.ErrorKeys;
+import org.apache.archiva.rest.api.v2.svc.ErrorMessage;
+import org.apache.archiva.rest.api.v2.svc.maven.MavenManagedRepositoryService;
+import org.apache.archiva.security.common.ArchivaRoleConstants;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static org.apache.archiva.security.common.ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
+import static org.apache.archiva.security.common.ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Service("v2.managedMavenRepositoryService#rest")
+public class DefaultMavenManagedRepositoryService implements MavenManagedRepositoryService
+{
+ @Context
+ HttpServletResponse httpServletResponse;
+
+ @Context
+ UriInfo uriInfo;
+
+ private static final Logger log = LoggerFactory.getLogger( DefaultMavenManagedRepositoryService.class );
+ private static final QueryHelper<ManagedRepository> QUERY_HELPER = new QueryHelper<>( new String[]{"id", "name"} );
+ static
+ {
+ QUERY_HELPER.addStringFilter( "id", ManagedRepository::getId );
+ QUERY_HELPER.addStringFilter( "name", ManagedRepository::getName );
+ QUERY_HELPER.addStringFilter( "location", (r) -> r.getLocation().toString() );
+ QUERY_HELPER.addBooleanFilter( "snapshot", (r) -> r.getActiveReleaseSchemes( ).contains( ReleaseScheme.SNAPSHOT ) );
+ QUERY_HELPER.addBooleanFilter( "release", (r) -> r.getActiveReleaseSchemes().contains( ReleaseScheme.RELEASE ));
+ QUERY_HELPER.addNullsafeFieldComparator( "id", ManagedRepository::getId );
+ QUERY_HELPER.addNullsafeFieldComparator( "name", ManagedRepository::getName );
+ }
+
+ private ManagedRepositoryAdmin managedRepositoryAdmin;
+ private RepositoryRegistry repositoryRegistry;
+ private SecuritySystem securitySystem;
+
+ public DefaultMavenManagedRepositoryService( SecuritySystem securitySystem,
+ RepositoryRegistry repositoryRegistry,
+ ManagedRepositoryAdmin managedRepositoryAdmin )
+ {
+ this.securitySystem = securitySystem;
+ this.repositoryRegistry = repositoryRegistry;
+ this.managedRepositoryAdmin = managedRepositoryAdmin;
+ }
+
+ protected AuditInformation getAuditInformation( )
+ {
+ RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get( );
+ User user;
+ String remoteAddr;
+ if (redbackRequestInformation==null) {
+ user = null;
+ remoteAddr = null;
+ } else
+ {
+ user = redbackRequestInformation.getUser( );
+ remoteAddr = redbackRequestInformation.getRemoteAddr( );
+ }
+ return new AuditInformation( user, remoteAddr );
+ }
+
+ @Override
+ public PagedResult<MavenManagedRepository> getManagedRepositories( final String searchTerm, final Integer offset,
+ final Integer limit, final List<String> orderBy,
+ final String order ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ Collection<ManagedRepository> repos = repositoryRegistry.getManagedRepositories( );
+ final Predicate<ManagedRepository> queryFilter = QUERY_HELPER.getQueryFilter( searchTerm ).and( r -> r.getType() == RepositoryType.MAVEN );
+ final Comparator<ManagedRepository> comparator = QUERY_HELPER.getComparator( orderBy, order );
+ int totalCount = Math.toIntExact( repos.stream( ).filter( queryFilter ).count( ) );
+ return PagedResult.of( totalCount, offset, limit, repos.stream( ).filter( queryFilter ).sorted( comparator )
+ .map(mr -> MavenManagedRepository.of(mr)).skip( offset ).limit( limit ).collect( Collectors.toList( ) ) );
+ }
+ catch (ArithmeticException e) {
+ log.error( "Invalid number of repositories detected." );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.INVALID_RESULT_SET_ERROR ) );
+ }
+ }
+
+ @Override
+ public MavenManagedRepository getManagedRepository( String repositoryId ) throws ArchivaRestServiceException
+ {
+ ManagedRepository repo = repositoryRegistry.getManagedRepository( repositoryId );
+ if (repo==null) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryId ), 404 );
+ }
+ if (repo.getType()!=RepositoryType.MAVEN) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_WRONG_TYPE, repositoryId, repo.getType().name() ), 404 );
+ }
+ return MavenManagedRepository.of( repo );
+ }
+
+ @Override
+ public Response deleteManagedRepository( String repositoryId, boolean deleteContent ) throws ArchivaRestServiceException
+ {
+ ManagedRepository repo = repositoryRegistry.getManagedRepository( repositoryId );
+ if (repo==null) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryId ), 404 );
+ }
+ if (repo.getType()!=RepositoryType.MAVEN) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_WRONG_TYPE, repositoryId, repo.getType().name() ), 404 );
+ }
+ try
+ {
+ managedRepositoryAdmin.deleteManagedRepository( repositoryId, getAuditInformation( ), deleteContent );
+ return Response.ok( ).build( );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_DELETE_FAILED, e.getMessage( ) ) );
+ }
+ }
+
+ private org.apache.archiva.admin.model.beans.ManagedRepository convert(MavenManagedRepository repository) {
+ org.apache.archiva.admin.model.beans.ManagedRepository repoBean = new org.apache.archiva.admin.model.beans.ManagedRepository( );
+ repoBean.setId( repository.getId( ) );
+ repoBean.setName( repository.getName() );
+ repoBean.setDescription( repository.getDescription() );
+ repoBean.setBlockRedeployments( repository.isBlocksRedeployments() );
+ repoBean.setCronExpression( repository.getSchedulingDefinition() );
+ repoBean.setLocation( repository.getLocation() );
+ repoBean.setReleases( repository.getReleaseSchemes().contains( ReleaseScheme.RELEASE.name() ) );
+ repoBean.setSnapshots( repository.getReleaseSchemes().contains( ReleaseScheme.SNAPSHOT.name() ) );
+ repoBean.setScanned( repository.isScanned() );
+ repoBean.setDeleteReleasedSnapshots( repository.isDeleteSnapshotsOfRelease() );
+ repoBean.setSkipPackedIndexCreation( repository.isSkipPackedIndexCreation() );
+ repoBean.setRetentionCount( repository.getRetentionCount() );
+ repoBean.setRetentionPeriod( repository.getRetentionPeriod().getDays() );
+ repoBean.setIndexDirectory( repository.getIndexPath() );
+ repoBean.setPackedIndexDirectory( repository.getPackedIndexPath() );
+ repoBean.setLayout( repository.getLayout() );
+ repoBean.setType( RepositoryType.MAVEN.name( ) );
+ return repoBean;
+ }
+
+ @Override
+ public MavenManagedRepository addManagedRepository( MavenManagedRepository managedRepository ) throws ArchivaRestServiceException
+ {
+ final String repoId = managedRepository.getId( );
+ if ( StringUtils.isEmpty( repoId ) ) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_INVALID_ID, repoId ), 422 );
+ }
+ Repository repo = repositoryRegistry.getRepository( repoId );
+ if (repo!=null) {
+ httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder( ).path( repoId ).build( ).toString( ) );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ID_EXISTS, repoId ), 303 );
+ }
+ try
+ {
+ managedRepositoryAdmin.addManagedRepository( convert( managedRepository ), managedRepository.isHasStagingRepository(), getAuditInformation() );
+ httpServletResponse.setStatus( 201 );
+ return MavenManagedRepository.of( repositoryRegistry.getManagedRepository( repoId ) );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
+ }
+ }
+
+ @Override
+ public MavenManagedRepository updateManagedRepository( final String repositoryId, final MavenManagedRepositoryUpdate managedRepository ) throws ArchivaRestServiceException
+ {
+ org.apache.archiva.admin.model.beans.ManagedRepository repo = convert( managedRepository );
+ try
+ {
+ managedRepositoryAdmin.updateManagedRepository( repo, managedRepository.isHasStagingRepository( ), getAuditInformation( ), managedRepository.isResetStats( ) );
+ ManagedRepository newRepo = repositoryRegistry.getManagedRepository( managedRepository.getId( ) );
+ if (newRepo==null) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_UPDATE_FAILED, repositoryId ) );
+ }
+ return MavenManagedRepository.of( newRepo );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
+ }
+ }
+
+ @Override
+ public FileInfo getFileStatus( String repositoryId, String fileLocation ) throws ArchivaRestServiceException
+ {
+ ManagedRepository repo = repositoryRegistry.getManagedRepository( repositoryId );
+ if (repo==null) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryId ), 404 );
+ }
+ try
+ {
+ ContentItem contentItem = repo.getContent( ).toItem( fileLocation );
+ if (contentItem.getAsset( ).exists( )) {
+ return FileInfo.of( contentItem.getAsset( ) );
+ } else {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.ARTIFACT_NOT_FOUND, repositoryId, fileLocation ), 404 );
+ }
+ }
+ catch ( LayoutException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_LAYOUT_ERROR, e.getMessage( ) ) );
+ }
+ }
+
+ @Override
+ public Response copyArtifact( String srcRepositoryId, String dstRepositoryId,
+ String path ) throws ArchivaRestServiceException
+ {
+ final AuditInformation auditInformation = getAuditInformation( );
+ final String userName = auditInformation.getUser( ).getUsername( );
+ if ( StringUtils.isEmpty( userName ) )
+ {
+ httpServletResponse.setHeader( "WWW-Authenticate", "Bearer realm=\"archiva\"" );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.NOT_AUTHENTICATED ), 401 );
+ }
+ ManagedRepository srcRepo = repositoryRegistry.getManagedRepository( srcRepositoryId );
+ if (srcRepo==null) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, srcRepositoryId ), 404 );
+ }
+ ManagedRepository dstRepo = repositoryRegistry.getManagedRepository( dstRepositoryId );
+ if (dstRepo==null) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, dstRepositoryId ), 404 );
+ }
+ checkAuthority( auditInformation.getUser().getUsername(), srcRepositoryId, dstRepositoryId );
+ try
+ {
+ ContentItem srcItem = srcRepo.getContent( ).toItem( path );
+ ContentItem dstItem = dstRepo.getContent( ).toItem( path );
+ if (!srcItem.getAsset().exists()){
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.ARTIFACT_NOT_FOUND, srcRepositoryId, path ), 404 );
+ }
+ if (dstItem.getAsset().exists()) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.ARTIFACT_EXISTS_AT_DEST, srcRepositoryId, path ), 400 );
+ }
+ FsStorageUtil.copyAsset( srcItem.getAsset( ), dstItem.getAsset( ), true );
+ }
+ catch ( LayoutException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_LAYOUT_ERROR, e.getMessage() ) );
+ }
+ catch ( IOException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.ARTIFACT_COPY_ERROR, e.getMessage() ) );
+ }
+ return Response.ok( ).build();
+ }
+
+ private void checkAuthority(final String userName, final String srcRepositoryId, final String dstRepositoryId ) throws ArchivaRestServiceException {
+ User user = null;
+ try
+ {
+ user = securitySystem.getUserManager().findUser( userName );
+ }
+ catch ( UserNotFoundException e )
+ {
+ httpServletResponse.setHeader( "WWW-Authenticate", "Bearer realm=\"archiva\"" );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.USER_NOT_FOUND, userName ), 401 );
+ }
+ catch ( UserManagerException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.USER_MANAGER_ERROR, e.getMessage( ) ) );
+ }
+
+ // check karma on source : read
+ AuthenticationResult authn = new AuthenticationResult( true, userName, null );
+ SecuritySession securitySession = new DefaultSecuritySession( authn, user );
+ try
+ {
+ boolean authz =
+ securitySystem.isAuthorized( securitySession, OPERATION_REPOSITORY_ACCESS,
+ srcRepositoryId );
+ if ( !authz )
+ {
+ throw new ArchivaRestServiceException(ErrorMessage.of( ErrorKeys.PERMISSION_REPOSITORY_DENIED, srcRepositoryId, OPERATION_REPOSITORY_ACCESS ), 403);
+ }
+ }
+ catch ( AuthorizationException e )
+ {
+ log.error( "Error reading permission: {}", e.getMessage(), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.AUTHORIZATION_ERROR, e.getMessage() ), 403);
+ }
+
+ // check karma on target: write
+ try
+ {
+ boolean authz =
+ securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD,
+ dstRepositoryId );
+ if ( !authz )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PERMISSION_REPOSITORY_DENIED, dstRepositoryId, OPERATION_REPOSITORY_UPLOAD ) );
+ }
+ }
+ catch ( AuthorizationException e )
+ {
+ log.error( "Error reading permission: {}", e.getMessage(), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.AUTHORIZATION_ERROR, e.getMessage() ), 403);
+ }
+
+
+ }
+
+ @Override
+ public Response deleteArtifact( String repositoryId, String path ) 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;
+ }
+
+}
--- /dev/null
+package org.apache.archiva.rest.v2.svc;/*
+ * 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 org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.components.rest.util.QueryHelper;
+import org.apache.archiva.configuration.RepositoryGroupConfiguration;
+import org.apache.archiva.repository.EditableRepositoryGroup;
+import org.apache.archiva.repository.RepositoryException;
+import org.apache.archiva.repository.RepositoryRegistry;
+import org.apache.archiva.repository.base.ConfigurationHandler;
+import org.apache.archiva.repository.validation.CheckedResult;
+import org.apache.archiva.repository.validation.ValidationError;
+import org.apache.archiva.rest.api.v2.model.MergeConfiguration;
+import org.apache.archiva.rest.api.v2.model.RepositoryGroup;
+import org.apache.archiva.rest.api.v2.svc.ArchivaRestServiceException;
+import org.apache.archiva.rest.api.v2.svc.ErrorKeys;
+import org.apache.archiva.rest.api.v2.svc.ErrorMessage;
+import org.apache.archiva.rest.api.v2.svc.RepositoryGroupService;
+import org.apache.archiva.rest.api.v2.svc.ValidationException;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * REST V2 Implementation for repository groups.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @see RepositoryGroupService
+ * @since 3.0
+ */
+@Service( "v2.repositoryGroupService#rest" )
+public class DefaultRepositoryGroupService implements RepositoryGroupService
+{
+ private final ConfigurationHandler configurationHandler;
+
+ @Context
+ HttpServletResponse httpServletResponse;
+
+ @Context
+ UriInfo uriInfo;
+
+ final private RepositoryRegistry repositoryRegistry;
+
+
+ private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryGroupService.class );
+ private static final QueryHelper<org.apache.archiva.repository.RepositoryGroup> QUERY_HELPER = new QueryHelper<>( new String[]{"id"} );
+
+ static
+ {
+ QUERY_HELPER.addStringFilter( "id", org.apache.archiva.repository.RepositoryGroup::getId );
+ QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.repository.RepositoryGroup::getId );
+ }
+
+
+ public DefaultRepositoryGroupService( RepositoryRegistry repositoryRegistry, ConfigurationHandler configurationHandler )
+ {
+ this.repositoryRegistry = repositoryRegistry;
+ this.configurationHandler = configurationHandler;
+ }
+
+ @Override
+ public PagedResult<RepositoryGroup> getRepositoriesGroups( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ Predicate<org.apache.archiva.repository.RepositoryGroup> filter = QUERY_HELPER.getQueryFilter( searchTerm );
+ Comparator<org.apache.archiva.repository.RepositoryGroup> ordering = QUERY_HELPER.getComparator( orderBy, QUERY_HELPER.isAscending( order ) );
+ int totalCount = Math.toIntExact( repositoryRegistry.getRepositoryGroups( ).stream( ).filter( filter ).count( ) );
+ List<RepositoryGroup> result = repositoryRegistry.getRepositoryGroups( ).stream( ).filter( filter ).sorted( ordering ).skip( offset ).limit( limit ).map(
+ RepositoryGroup::of
+ ).collect( Collectors.toList( ) );
+ return new PagedResult<>( totalCount, offset, limit, result );
+ }
+ catch ( ArithmeticException e )
+ {
+ log.error( "Could not convert total count: {}", e.getMessage( ) );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.INVALID_RESULT_SET_ERROR ) );
+ }
+
+ }
+
+ @Override
+ public RepositoryGroup getRepositoryGroup( String repositoryGroupId ) throws ArchivaRestServiceException
+ {
+ if ( StringUtils.isEmpty( repositoryGroupId ) )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
+ }
+ org.apache.archiva.repository.RepositoryGroup group = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
+ return RepositoryGroup.of( group );
+ }
+
+ private RepositoryGroupConfiguration toConfig( RepositoryGroup group )
+ {
+ RepositoryGroupConfiguration result = new RepositoryGroupConfiguration( );
+ result.setId( group.getId( ) );
+ result.setName( group.getName() );
+ result.setLocation( group.getLocation( ) );
+ result.setRepositories( group.getRepositories( ) );
+ MergeConfiguration mergeConfig = group.getMergeConfiguration( );
+ if ( mergeConfig != null )
+ {
+ result.setMergedIndexPath( mergeConfig.getMergedIndexPath( ) );
+ result.setMergedIndexTtl( mergeConfig.getMergedIndexTtlMinutes( ) );
+ result.setCronExpression( mergeConfig.getIndexMergeSchedule( ) );
+ }
+ return result;
+ }
+
+ @Override
+ public RepositoryGroup addRepositoryGroup( RepositoryGroup repositoryGroup ) throws ArchivaRestServiceException
+ {
+ final String groupId = repositoryGroup.getId( );
+ if ( StringUtils.isEmpty( groupId ) )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_INVALID_ID, groupId ), 422 );
+ }
+ if ( repositoryRegistry.hasRepositoryGroup( groupId ) )
+ {
+ httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder( ).path( groupId ).build( ).toString( ) );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ID_EXISTS, groupId ), 303 );
+ }
+ try
+ {
+
+ RepositoryGroupConfiguration configuration = toConfig( repositoryGroup );
+ CheckedResult<org.apache.archiva.repository.RepositoryGroup, Map<String, List<ValidationError>>> validationResult = repositoryRegistry.putRepositoryGroupAndValidate( configuration );
+ if ( validationResult.isValid( ) )
+ {
+ httpServletResponse.setStatus( 201 );
+ return RepositoryGroup.of( validationResult.getRepository( ) );
+ }
+ else
+ {
+ throw ValidationException.of( validationResult.getResult( ) );
+ }
+ }
+ catch ( RepositoryException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_ADD_FAILED ) );
+ }
+ }
+
+ @Override
+ public RepositoryGroup updateRepositoryGroup( final String repositoryGroupId, final RepositoryGroup repositoryGroup ) throws ArchivaRestServiceException
+ {
+ if ( StringUtils.isEmpty( repositoryGroupId ) )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
+ }
+ if ( !repositoryRegistry.hasRepositoryGroup( repositoryGroupId ) )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND ), 404 );
+ }
+ repositoryGroup.setId( repositoryGroupId );
+ try
+ {
+ RepositoryGroupConfiguration configuration = toConfig( repositoryGroup );
+ CheckedResult<org.apache.archiva.repository.RepositoryGroup, Map<String, List<ValidationError>>> validationResult = repositoryRegistry.putRepositoryGroupAndValidate( configuration );
+ if ( validationResult.isValid( ) )
+ {
+ httpServletResponse.setStatus( 201 );
+ return RepositoryGroup.of( validationResult.getRepository( ) );
+ }
+ else
+ {
+ throw ValidationException.of( validationResult.getResult( ) );
+ }
+ }
+ catch ( RepositoryException e )
+ {
+ log.error( "Exception during repository group update: {}", e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage( ) ) );
+
+ }
+ }
+
+ @Override
+ public Response deleteRepositoryGroup( String repositoryGroupId ) throws ArchivaRestServiceException
+ {
+ if ( StringUtils.isEmpty( repositoryGroupId ) )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
+ }
+ try
+ {
+ org.apache.archiva.repository.RepositoryGroup group = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
+ if ( group == null )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
+ }
+ repositoryRegistry.removeRepositoryGroup( group );
+ return Response.ok( ).build( );
+ }
+ catch ( RepositoryException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_DELETE_FAILED ) );
+ }
+ }
+
+ @Override
+ public RepositoryGroup addRepositoryToGroup( String repositoryGroupId, String repositoryId ) throws ArchivaRestServiceException
+ {
+ if ( StringUtils.isEmpty( repositoryGroupId ) )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
+ }
+ if ( StringUtils.isEmpty( repositoryId ) )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
+ }
+ try
+ {
+ org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
+ if ( repositoryGroup == null )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
+ }
+ if ( !( repositoryGroup instanceof EditableRepositoryGroup ) )
+ {
+ log.error( "This group instance is not editable: {}", repositoryGroupId );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, "" ), 500 );
+ }
+ EditableRepositoryGroup editableRepositoryGroup = (EditableRepositoryGroup) repositoryGroup;
+ if ( editableRepositoryGroup.getRepositories( ).stream( ).anyMatch( repo -> repositoryId.equals( repo.getId( ) ) ) )
+ {
+ log.info( "Repository {} is already member of group {}", repositoryId, repositoryGroupId );
+ return RepositoryGroup.of( editableRepositoryGroup );
+ }
+ org.apache.archiva.repository.ManagedRepository managedRepo = repositoryRegistry.getManagedRepository( repositoryId );
+ if ( managedRepo == null )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
+ }
+ editableRepositoryGroup.addRepository( managedRepo );
+ org.apache.archiva.repository.RepositoryGroup newGroup = repositoryRegistry.putRepositoryGroup( editableRepositoryGroup );
+ return RepositoryGroup.of( newGroup );
+ }
+ catch ( RepositoryException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage( ) ), 500 );
+ }
+ }
+
+ @Override
+ public RepositoryGroup deleteRepositoryFromGroup( final String repositoryGroupId, final String repositoryId ) throws ArchivaRestServiceException
+ {
+ if ( StringUtils.isEmpty( repositoryGroupId ) )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, repositoryGroupId ), 404 );
+ }
+ if ( StringUtils.isEmpty( repositoryId ) )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryId ), 404 );
+ }
+ try
+ {
+ org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
+ if ( repositoryGroup == null )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
+ }
+ if ( repositoryGroup.getRepositories( ).stream( ).noneMatch( r -> repositoryId.equals( r.getId( ) ) ) )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryId ), 404 );
+ }
+ if ( !( repositoryGroup instanceof EditableRepositoryGroup ) )
+ {
+ log.error( "This group instance is not editable: {}", repositoryGroupId );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, "" ), 500 );
+ }
+ EditableRepositoryGroup editableRepositoryGroup = (EditableRepositoryGroup) repositoryGroup;
+ editableRepositoryGroup.removeRepository( repositoryId );
+ org.apache.archiva.repository.RepositoryGroup newGroup = repositoryRegistry.putRepositoryGroup( editableRepositoryGroup );
+ return RepositoryGroup.of( newGroup );
+ }
+ catch ( RepositoryException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage( ) ), 500 );
+ }
+ }
+
+
+}
--- /dev/null
+package org.apache.archiva.rest.v2.svc;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.admin.model.RepositoryAdminException;
+import org.apache.archiva.admin.model.admin.RepositoryTaskAdministration;
+import org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.components.rest.util.QueryHelper;
+import org.apache.archiva.components.rest.util.RestUtil;
+import org.apache.archiva.metadata.repository.MetadataRepositoryException;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
+import org.apache.archiva.repository.RemoteRepository;
+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.v2.model.Repository;
+import org.apache.archiva.rest.api.v2.model.RepositoryStatistics;
+import org.apache.archiva.rest.api.v2.model.ScanStatus;
+import org.apache.archiva.rest.api.v2.svc.ArchivaRestServiceException;
+import org.apache.archiva.rest.api.v2.svc.ErrorKeys;
+import org.apache.archiva.rest.api.v2.svc.ErrorMessage;
+import org.apache.archiva.rest.api.v2.svc.RepositoryService;
+import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexException;
+import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexScheduler;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Named;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Service( "v2.repositoryService#rest" )
+public class DefaultRepositoryService implements RepositoryService
+{
+
+ final
+ RepositoryRegistry repositoryRegistry;
+
+ final
+ RepositoryStatisticsManager repositoryStatisticsManager;
+
+ private final RepositoryTaskAdministration repositoryTaskAdministration;
+
+ private final RepositoryScanner repoScanner;
+
+ private final DownloadRemoteIndexScheduler downloadRemoteIndexScheduler;
+
+ private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryService.class );
+ private static final QueryHelper<org.apache.archiva.repository.Repository> QUERY_HELPER = new QueryHelper<>( new String[]{"id", "name"} );
+
+ static
+ {
+ QUERY_HELPER.addStringFilter( "id", org.apache.archiva.repository.Repository::getId );
+ QUERY_HELPER.addStringFilter( "name", org.apache.archiva.repository.Repository::getName );
+ QUERY_HELPER.addStringFilter( "description", org.apache.archiva.repository.Repository::getDescription );
+ QUERY_HELPER.addStringFilter( "type", repo -> repo.getType( ).name( ) );
+ QUERY_HELPER.addBooleanFilter( "scanned", org.apache.archiva.repository.Repository::isScanned );
+ QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.repository.Repository::getId );
+ QUERY_HELPER.addNullsafeFieldComparator( "name", org.apache.archiva.repository.Repository::getName );
+ QUERY_HELPER.addNullsafeFieldComparator( "type", repo -> repo.getType( ).name( ) );
+ QUERY_HELPER.addNullsafeFieldComparator( "boolean", org.apache.archiva.repository.Repository::isScanned );
+ }
+
+ public DefaultRepositoryService( RepositoryRegistry repositoryRegistry, RepositoryStatisticsManager repositoryStatisticsManager,
+ @Named( value = "repositoryTaskAdministration#default") RepositoryTaskAdministration repositoryTaskAdministration,
+ RepositoryScanner repoScanner, DownloadRemoteIndexScheduler downloadRemoteIndexScheduler )
+ {
+ this.repositoryRegistry = repositoryRegistry;
+ this.repositoryStatisticsManager = repositoryStatisticsManager;
+ this.repoScanner = repoScanner;
+ this.repositoryTaskAdministration = repositoryTaskAdministration;
+ this.downloadRemoteIndexScheduler = downloadRemoteIndexScheduler;
+ }
+
+ private void handleAdminException( RepositoryAdminException e ) throws ArchivaRestServiceException
+ {
+ log.error( "Repository admin error: {}", e.getMessage( ), e );
+ if ( e.keyExists( ) )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PREFIX + e.getKey( ), e.getParameters( ) ) );
+ }
+ else
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
+ }
+ }
+
+
+ @Override
+ public PagedResult<Repository> getRepositories( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order,
+ String localeString ) throws ArchivaRestServiceException
+ {
+ final Locale locale = StringUtils.isNotEmpty( localeString ) ? Locale.forLanguageTag( localeString ) : Locale.getDefault( );
+ boolean isAscending = QUERY_HELPER.isAscending( order );
+ Predicate<org.apache.archiva.repository.Repository> filter = QUERY_HELPER.getQueryFilter( searchTerm );
+ Comparator<org.apache.archiva.repository.Repository> comparator = QUERY_HELPER.getComparator( orderBy, isAscending );
+ try
+ {
+ int totalCount = Math.toIntExact( repositoryRegistry.getRepositories( ).stream( ).filter( filter ).count( ) );
+ return new PagedResult<>( totalCount, offset, limit, repositoryRegistry.getRepositories( ).stream( )
+ .filter( filter ).skip( offset ).limit( limit ).sorted( comparator ).map( repo -> Repository.of( repo, locale ) )
+ .collect( Collectors.toList( ) ) );
+ }
+ catch ( ArithmeticException e )
+ {
+ log.error( "Invalid integer conversion for totalCount" );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.INVALID_RESULT_SET_ERROR ) );
+ }
+ }
+
+ @Override
+ public RepositoryStatistics getManagedRepositoryStatistics( String repositoryId ) throws ArchivaRestServiceException
+ {
+ if ( repositoryRegistry.getManagedRepository( repositoryId ) == null )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_MANAGED_NOT_FOUND, repositoryId ), 404 );
+ }
+ try
+ {
+ return RepositoryStatistics.of( repositoryStatisticsManager.getLastStatistics( repositoryId ) );
+ }
+ catch ( MetadataRepositoryException e )
+ {
+ log.error( "Metadata error: {} ", e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_METADATA_ERROR, e.getMessage( ) ) );
+ }
+ }
+
+ @Override
+ public Response scheduleRepositoryScan( String repositoryId, boolean fullScan ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ repositoryTaskAdministration.scheduleFullScan( repositoryId );
+ return Response.ok( ).build( );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ handleAdminException( e );
+ return Response.serverError( ).build( );
+ }
+ }
+
+ @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
+ {
+ try
+ {
+ return ScanStatus.of( repositoryTaskAdministration.getCurrentScanStatus( ) );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ handleAdminException( e );
+ return new ScanStatus();
+ }
+ }
+
+ @Override
+ public Response removeScanningTaskFromQueue( String repositoryId ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ repositoryTaskAdministration.cancelTasks( repositoryId );
+ return Response.ok( ).build( );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ handleAdminException( e );
+ return Response.serverError( ).build( );
+ }
+ }
+
+
+ @Override
+ public Response scheduleDownloadRemoteIndex( String repositoryId, boolean immediately, boolean full,
+ UriInfo uriInfo ) throws ArchivaRestServiceException
+ {
+ boolean immediateSet = RestUtil.isFlagSet( uriInfo, "immediate" );
+ boolean fullSet = RestUtil.isFlagSet( uriInfo, "full" );
+ RemoteRepository repo = repositoryRegistry.getRemoteRepository( repositoryId );
+ if (repo==null) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_REMOTE_NOT_FOUND, repositoryId ), 404 );
+ }
+ try
+ {
+ downloadRemoteIndexScheduler.scheduleDownloadRemote( repositoryId, immediateSet, fullSet );
+ return Response.ok( ).build( );
+ }
+ catch ( DownloadRemoteIndexException e )
+ {
+ log.error( "Could not schedule index download for repository {}: {}", repositoryId, e.getMessage(), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_REMOTE_INDEX_DOWNLOAD_FAILED, e.getMessage( ) ) );
+ }
+ }
+
+
+
+ @Override
+ public List<String> getRunningRemoteDownloads( )
+ {
+ return downloadRemoteIndexScheduler.getRunningRemoteDownloadIds( );
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.v2.svc;/*
+ * 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 org.apache.archiva.admin.model.RepositoryAdminException;
+import org.apache.archiva.admin.model.beans.RedbackRuntimeConfiguration;
+import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin;
+import org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.components.rest.model.PropertyEntry;
+import org.apache.archiva.components.rest.util.QueryHelper;
+import org.apache.archiva.redback.authentication.Authenticator;
+import org.apache.archiva.redback.common.ldap.connection.LdapConnection;
+import org.apache.archiva.redback.common.ldap.connection.LdapConnectionConfiguration;
+import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory;
+import org.apache.archiva.redback.common.ldap.connection.LdapException;
+import org.apache.archiva.redback.common.ldap.user.LdapUserMapper;
+import org.apache.archiva.redback.policy.CookieSettings;
+import org.apache.archiva.redback.policy.PasswordRule;
+import org.apache.archiva.redback.rbac.RBACManager;
+import org.apache.archiva.redback.role.RoleManager;
+import org.apache.archiva.redback.users.UserManager;
+import org.apache.archiva.rest.api.v2.model.BeanInformation;
+import org.apache.archiva.rest.api.v2.model.CacheConfiguration;
+import org.apache.archiva.rest.api.v2.model.LdapConfiguration;
+import org.apache.archiva.rest.api.v2.model.SecurityConfiguration;
+import org.apache.archiva.rest.api.v2.svc.ArchivaRestServiceException;
+import org.apache.archiva.rest.api.v2.svc.ErrorKeys;
+import org.apache.archiva.rest.api.v2.svc.ErrorMessage;
+import org.apache.archiva.rest.api.v2.svc.SecurityConfigurationService;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.naming.AuthenticationException;
+import javax.naming.AuthenticationNotSupportedException;
+import javax.naming.CommunicationException;
+import javax.naming.InvalidNameException;
+import javax.naming.NamingException;
+import javax.naming.NoPermissionException;
+import javax.naming.ServiceUnavailableException;
+import javax.ws.rs.core.Response;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static org.apache.archiva.rest.api.v2.svc.ErrorKeys.INVALID_RESULT_SET_ERROR;
+import static org.apache.archiva.rest.api.v2.svc.ErrorKeys.REPOSITORY_ADMIN_ERROR;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Service( "v2.defaultSecurityConfigurationService" )
+public class DefaultSecurityConfigurationService implements SecurityConfigurationService
+{
+ private static final Logger log = LoggerFactory.getLogger( DefaultSecurityConfigurationService.class );
+
+ private static final String[] KNOWN_LDAP_CONTEXT_PROVIDERS = {"com.sun.jndi.ldap.LdapCtxFactory","com.ibm.jndi.LDAPCtxFactory"};
+ private final List<String> availableContextProviders = new ArrayList<>( );
+
+ private static final QueryHelper<PropertyEntry> PROP_QUERY_HELPER = new QueryHelper<>( new String[]{"key"} );
+
+ static
+ {
+ PROP_QUERY_HELPER.addStringFilter( "key", PropertyEntry::getKey );
+ PROP_QUERY_HELPER.addStringFilter( "value", PropertyEntry::getValue );
+ PROP_QUERY_HELPER.addNullsafeFieldComparator( "key", PropertyEntry::getKey );
+ PROP_QUERY_HELPER.addNullsafeFieldComparator( "value", PropertyEntry::getValue );
+
+ }
+
+ private ResourceBundle bundle;
+
+
+ @Inject
+ private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin;
+
+ @Inject
+ private ApplicationContext applicationContext;
+
+ @Inject
+ @Named( value = "userManager#default" )
+ private UserManager userManager;
+
+ @Inject
+ @Named( value = "rbacManager#default" )
+ private RBACManager rbacManager;
+
+ @Inject
+ private RoleManager roleManager;
+
+ @Inject
+ @Named( value = "ldapConnectionFactory#configurable" )
+ private LdapConnectionFactory ldapConnectionFactory;
+
+ @Inject
+ private LdapUserMapper ldapUserMapper;
+
+
+ @PostConstruct
+ void init( )
+ {
+ bundle = ResourceBundle.getBundle( "org.apache.archiva.rest.RestBundle" );
+ for (String ldapClass : KNOWN_LDAP_CONTEXT_PROVIDERS) {
+ if (isContextFactoryAvailable( ldapClass )) {
+ availableContextProviders.add( ldapClass );
+ }
+ }
+ }
+
+ @Override
+ public SecurityConfiguration getConfiguration( ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ RedbackRuntimeConfiguration redbackRuntimeConfiguration =
+ redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
+
+ log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
+
+ return SecurityConfiguration.ofRedbackConfiguration( redbackRuntimeConfiguration );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
+ }
+ }
+
+ private void updateConfig( SecurityConfiguration newConfig, RedbackRuntimeConfiguration rbConfig )
+ {
+ rbConfig.setUserManagerImpls( newConfig.getActiveUserManagers( ) );
+ rbConfig.setRbacManagerImpls( newConfig.getActiveRbacManagers( ) );
+ rbConfig.setUseUsersCache( newConfig.isUserCacheEnabled( ) );
+ Map<String, String> props = rbConfig.getConfigurationProperties( );
+ for ( Map.Entry<String, String> newProp : newConfig.getProperties( ).entrySet( ) )
+ {
+ props.put( newProp.getKey( ), newProp.getValue( ) );
+ }
+ }
+
+ private void updateConfig( LdapConfiguration newConfig, RedbackRuntimeConfiguration rbConfig )
+ {
+ org.apache.archiva.admin.model.beans.LdapConfiguration ldapConfig = rbConfig.getLdapConfiguration( );
+ ldapConfig.setBaseDn( newConfig.getBaseDn( ) );
+ ldapConfig.setAuthenticationMethod( newConfig.getAuthenticationMethod( ) );
+ ldapConfig.setBindAuthenticatorEnabled( newConfig.isBindAuthenticatorEnabled( ) );
+ ldapConfig.setBindDn( newConfig.getBindDn( ) );
+ ldapConfig.setSsl( newConfig.isSslEnabled( ) );
+ ldapConfig.setBaseGroupsDn( newConfig.getGroupsBaseDn( ) );
+ ldapConfig.setHostName( newConfig.getHostName( ) );
+ ldapConfig.setPort( newConfig.getPort( ) );
+ ldapConfig.setPassword( newConfig.getBindPassword( ) );
+ ldapConfig.setUseRoleNameAsGroup( newConfig.isUseRoleNameAsGroup( ) );
+ ldapConfig.setWritable( newConfig.isWritable( ) );
+ ldapConfig.setContextFactory( newConfig.getContextFactory( ) );
+
+ Map<String, String> props = ldapConfig.getExtraProperties( );
+ for ( Map.Entry<String, String> newProp : newConfig.getProperties( ).entrySet( ) )
+ {
+ props.put( newProp.getKey( ), newProp.getValue( ) );
+ }
+ }
+
+ private void updateConfig( CacheConfiguration newConfig, RedbackRuntimeConfiguration rbConfig )
+ {
+ org.apache.archiva.admin.model.beans.CacheConfiguration cacheConfig = rbConfig.getUsersCacheConfiguration( );
+ cacheConfig.setMaxElementsInMemory( newConfig.getMaxEntriesInMemory( ) );
+ cacheConfig.setMaxElementsOnDisk( newConfig.getMaxEntriesOnDisk( ) );
+ cacheConfig.setTimeToLiveSeconds( newConfig.getTimeToLiveSeconds( ) );
+ cacheConfig.setTimeToIdleSeconds( newConfig.getTimeToIdleSeconds( ) );
+ }
+
+ @Override
+ public SecurityConfiguration updateConfiguration( SecurityConfiguration newConfiguration ) throws ArchivaRestServiceException
+ {
+ if ( newConfiguration == null )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.MISSING_DATA ), 400 );
+ }
+ try
+ {
+ RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
+ boolean userManagerChanged = !CollectionUtils.isEqualCollection( newConfiguration.getActiveUserManagers( ), conf.getUserManagerImpls( ) );
+ boolean rbacManagerChanged = !CollectionUtils.isEqualCollection( newConfiguration.getActiveRbacManagers( ), conf.getRbacManagerImpls( ) );
+
+ boolean ldapConfigured = newConfiguration.getActiveUserManagers( ).stream( ).anyMatch( um -> um.contains( "ldap" ) );
+ if ( !ldapConfigured )
+ {
+ ldapConfigured= newConfiguration.getActiveRbacManagers( ).stream( ).anyMatch( um -> um.contains( "ldap" ) );
+ }
+
+ updateConfig( newConfiguration, conf );
+ redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( conf );
+
+ if ( userManagerChanged )
+ {
+ log.info( "user managerImpls changed to {} so reload it",
+ newConfiguration.getActiveUserManagers( ) );
+ userManager.initialize( );
+ }
+
+ if ( rbacManagerChanged )
+ {
+ log.info( "rbac manager changed to {} so reload it",
+ newConfiguration.getActiveRbacManagers( ) );
+ rbacManager.initialize( );
+ roleManager.initialize( );
+ }
+
+ if ( ldapConfigured )
+ {
+ try
+ {
+ ldapConnectionFactory.initialize( );
+ }
+ catch ( Exception e )
+ {
+ log.error( "Could not initialize LDAP connection factory: {}", e.getMessage( ) );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_CF_INIT_FAILED, e.getMessage( ) ) );
+ }
+ }
+ Collection<PasswordRule> passwordRules = applicationContext.getBeansOfType( PasswordRule.class ).values( );
+
+ for ( PasswordRule passwordRule : passwordRules )
+ {
+ passwordRule.initialize( );
+ }
+
+ Collection<CookieSettings> cookieSettingsList =
+ applicationContext.getBeansOfType( CookieSettings.class ).values( );
+
+ for ( CookieSettings cookieSettings : cookieSettingsList )
+ {
+ cookieSettings.initialize( );
+ }
+
+ Collection<Authenticator> authenticators =
+ applicationContext.getBeansOfType( Authenticator.class ).values( );
+
+ for ( Authenticator authenticator : authenticators )
+ {
+ try
+ {
+ log.debug( "Initializing authenticatior " + authenticator.getId( ) );
+ authenticator.initialize( );
+ }
+ catch ( Exception e )
+ {
+ log.error( "Initialization of authenticator failed " + authenticator.getId( ), e );
+ }
+ }
+
+ if ( ldapConfigured )
+ {
+ try
+ {
+ ldapUserMapper.initialize( );
+ }
+ catch ( Exception e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_USER_MAPPER_INIT_FAILED, e.getMessage( ) ) );
+ }
+ }
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
+ }
+ try
+ {
+ return SecurityConfiguration.ofRedbackConfiguration( redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( ) );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ log.error( "Error while retrieve updated configuration: {}", e.getMessage( ) );
+ throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
+ }
+ }
+
+ @Override
+ public PagedResult<PropertyEntry> getConfigurationProperties( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ RedbackRuntimeConfiguration redbackRuntimeConfiguration =
+ redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
+
+ log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
+
+ boolean ascending = PROP_QUERY_HELPER.isAscending( order );
+ Predicate<PropertyEntry> filter = PROP_QUERY_HELPER.getQueryFilter( searchTerm );
+ Comparator<PropertyEntry> comparator = PROP_QUERY_HELPER.getComparator( orderBy, ascending );
+ Map<String, String> props = redbackRuntimeConfiguration.getConfigurationProperties( );
+ int totalCount = Math.toIntExact( props.entrySet( ).stream( ).map(
+ entry -> new PropertyEntry( entry.getKey( ), entry.getValue( ) )
+ ).filter( filter ).count( ) );
+ List<PropertyEntry> result = props.entrySet( ).stream( ).map(
+ entry -> new PropertyEntry( entry.getKey( ), entry.getValue( ) )
+ ).filter( filter )
+ .sorted( comparator )
+ .skip( offset ).limit( limit )
+ .collect( Collectors.toList( ) );
+ return new PagedResult<>( totalCount, offset, limit, result );
+ } catch (ArithmeticException e) {
+ log.error( "The total count of the result properties is higher than max integer value!" );
+ throw new ArchivaRestServiceException( ErrorMessage.of( INVALID_RESULT_SET_ERROR ) );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
+ }
+ }
+
+ @Override
+ public PropertyEntry getConfigurationProperty( String propertyName ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
+ if ( conf.getConfigurationProperties( ).containsKey( propertyName ) )
+ {
+ String value = conf.getConfigurationProperties( ).get( propertyName );
+ return new PropertyEntry( propertyName, value );
+ }
+ else
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PROPERTY_NOT_FOUND ), 404 );
+ }
+
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
+ }
+
+ }
+
+ @Override
+ public Response updateConfigurationProperty( String propertyName, PropertyEntry propertyValue ) throws ArchivaRestServiceException
+ {
+ if ( propertyValue == null )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.MISSING_DATA ), 400 );
+ }
+ try
+ {
+ RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
+ if ( conf.getConfigurationProperties( ).containsKey( propertyName ) )
+ {
+ conf.getConfigurationProperties( ).put( propertyName, propertyValue.getValue( ) );
+ redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( conf );
+ return Response.ok( ).build( );
+ }
+ else
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PROPERTY_NOT_FOUND ), 404 );
+ }
+
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
+ }
+ }
+
+ @Override
+ public LdapConfiguration getLdapConfiguration( ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ RedbackRuntimeConfiguration redbackRuntimeConfiguration =
+ redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
+
+ log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
+
+ LdapConfiguration ldapConfig = LdapConfiguration.of( redbackRuntimeConfiguration.getLdapConfiguration( ) );
+ ldapConfig.setAvailableContextFactories( availableContextProviders );
+ return ldapConfig;
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
+ }
+
+ }
+
+ @Override
+ public LdapConfiguration updateLdapConfiguration( LdapConfiguration configuration ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ RedbackRuntimeConfiguration redbackRuntimeConfiguration =
+ redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
+
+ log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
+
+ updateConfig( configuration, redbackRuntimeConfiguration );
+
+ redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration );
+ ldapConnectionFactory.initialize( );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
+ }
+
+ try
+ {
+ return LdapConfiguration.of( redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( ).getLdapConfiguration() );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ log.error( "Error while retrieve updated configuration: {}", e.getMessage( ) );
+ throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
+ }
+
+ }
+
+ static Properties toProperties( Map<String, String> values )
+ {
+ Properties result = new Properties( );
+ for ( Map.Entry<String, String> entry : values.entrySet( ) )
+ {
+ result.setProperty( entry.getKey( ), entry.getValue( ) );
+ }
+ return result;
+ }
+
+ private static boolean isContextFactoryAvailable( final String factoryClass)
+ {
+ try
+ {
+ return Thread.currentThread().getContextClassLoader().loadClass( factoryClass )
+ != null;
+ }
+ catch ( ClassNotFoundException e )
+ {
+ return false;
+ }
+ }
+
+
+ @Override
+ public Response verifyLdapConfiguration( LdapConfiguration ldapConfiguration ) throws ArchivaRestServiceException
+ {
+ LdapConnection ldapConnection = null;
+ try
+ {
+ LdapConnectionConfiguration ldapConnectionConfiguration =
+ new LdapConnectionConfiguration( ldapConfiguration.getHostName( ), ldapConfiguration.getPort( ),
+ ldapConfiguration.getBaseDn( ), ldapConfiguration.getContextFactory( ),
+ ldapConfiguration.getBindDn( ), ldapConfiguration.getBindPassword( ),
+ ldapConfiguration.getAuthenticationMethod( ),
+ toProperties( ldapConfiguration.getProperties( ) ) );
+ ldapConnectionConfiguration.setSsl( ldapConfiguration.isSslEnabled( ) );
+
+ ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration );
+ }
+ catch ( InvalidNameException e )
+ {
+ log.warn( "LDAP connection check failed with invalid name : {}", e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_INVALID_NAME, e.getMessage( ) ), 400 );
+ }
+ catch ( LdapException e )
+ {
+ handleLdapException( e );
+ }
+ finally
+ {
+ if ( ldapConnection != null )
+ {
+ try
+ {
+ ldapConnection.close( );
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Could not close connection: {}", e.getMessage( ) );
+ }
+ }
+ ldapConnection = null;
+ }
+
+ try
+ {
+ // verify groups dn value too
+
+ LdapConnectionConfiguration ldapConnectionConfiguration = new LdapConnectionConfiguration( ldapConfiguration.getHostName( ), ldapConfiguration.getPort( ),
+ ldapConfiguration.getGroupsBaseDn( ),
+ ldapConfiguration.getContextFactory( ), ldapConfiguration.getBindDn( ),
+ ldapConfiguration.getBindPassword( ),
+ ldapConfiguration.getAuthenticationMethod( ),
+ toProperties( ldapConfiguration.getProperties( ) ) );
+
+ ldapConnectionConfiguration.setSsl( ldapConfiguration.isSslEnabled( ) );
+
+ ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration );
+ }
+ catch ( InvalidNameException e )
+ {
+ log.warn( "LDAP connection check failed with invalid name : {}", e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_INVALID_NAME, e.getMessage( ) ), 400 );
+ }
+ catch ( LdapException e )
+ {
+ handleLdapException( e );
+ }
+ finally
+ {
+ if ( ldapConnection != null )
+ {
+ try
+ {
+ ldapConnection.close( );
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Could not close connection: {}", e.getMessage( ), e );
+ }
+ }
+ }
+
+ return Response.ok( ).build( );
+ }
+
+ private void handleLdapException( LdapException e ) throws ArchivaRestServiceException
+ {
+ Throwable rootCause = e.getRootCause( );
+ if ( rootCause instanceof CommunicationException )
+ {
+ log.warn( "LDAP connection check failed with CommunicationException: {}", e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_COMMUNICATION_ERROR, e.getMessage( ) ), 400 );
+ } else if (rootCause instanceof ServiceUnavailableException ) {
+ log.warn( "LDAP connection check failed with ServiceUnavailableException: {}", e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_UNAVAILABLE, e.getMessage( ) ), 400 );
+ } else if (rootCause instanceof AuthenticationException ) {
+ log.warn( "LDAP connection check failed with AuthenticationException: {}", e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_AUTHENTICATION_FAILED, e.getMessage( ) ), 400 );
+ } else if (rootCause instanceof AuthenticationNotSupportedException ) {
+ log.warn( "LDAP connection check failed with AuthenticationNotSupportedException: {}", e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_AUTHENTICATION_NOT_SUPPORTED, e.getMessage( ) ), 400 );
+ } else if (rootCause instanceof NoPermissionException ) {
+ log.warn( "LDAP connection check failed with NoPermissionException: {}", e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_NO_PERMISSION, e.getMessage( ) ), 400 );
+ }
+ log.warn( "LDAP connection check failed: {} - {}", e.getClass().getName(), e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_GENERIC_ERROR, e.getMessage( ) ), 400 );
+ }
+
+ @Override
+ public CacheConfiguration getCacheConfiguration( ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ RedbackRuntimeConfiguration redbackRuntimeConfiguration =
+ redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
+
+ log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
+
+ return CacheConfiguration.of( redbackRuntimeConfiguration.getUsersCacheConfiguration( ) );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
+ }
+
+ }
+
+ @Override
+ public CacheConfiguration updateCacheConfiguration( CacheConfiguration cacheConfiguration ) throws ArchivaRestServiceException
+ {
+ if ( cacheConfiguration == null )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.MISSING_DATA ), 400 );
+ }
+ try
+ {
+ RedbackRuntimeConfiguration redbackRuntimeConfiguration =
+ redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
+
+ log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
+ updateConfig( cacheConfiguration, redbackRuntimeConfiguration );
+ redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration );
+ return getCacheConfiguration( );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
+ }
+ }
+
+ @Override
+ public List<BeanInformation> getAvailableUserManagers( )
+ {
+ Map<String, UserManager> beans = applicationContext.getBeansOfType( UserManager.class );
+
+ if ( beans.isEmpty( ) )
+ {
+ return Collections.emptyList( );
+ }
+
+ return beans.entrySet( ).stream( )
+ .filter( entry -> entry.getValue( ).isFinalImplementation( ) )
+ .map( ( Map.Entry<String, UserManager> entry ) -> {
+ UserManager um = entry.getValue( );
+ String id = StringUtils.substringAfter( entry.getKey( ), "#" );
+ String displayName = bundle.getString( "user_manager." + id + ".display_name" );
+ String description = bundle.getString( "user_manager." + id + ".description" );
+ return new BeanInformation( StringUtils.substringAfter( entry.getKey( ), "#" ), displayName, um.getDescriptionKey( ), description, um.isReadOnly( ) );
+ } ).collect( Collectors.toList( ) );
+ }
+
+ @Override
+ public List<BeanInformation> getAvailableRbacManagers( )
+ {
+ Map<String, RBACManager> beans = applicationContext.getBeansOfType( RBACManager.class );
+
+ if ( beans.isEmpty( ) )
+ {
+ return Collections.emptyList( );
+ }
+
+ return beans.entrySet( ).stream( )
+ .filter( entry -> entry.getValue( ).isFinalImplementation( ) )
+ .map( ( Map.Entry<String, RBACManager> entry ) -> {
+ RBACManager rm = entry.getValue( );
+ String id = StringUtils.substringAfter( entry.getKey( ), "#" );
+ String displayName = bundle.getString( "rbac_manager." + id + ".display_name" );
+ String description = bundle.getString( "rbac_manager." + id + ".description" );
+ return new BeanInformation( StringUtils.substringAfter( entry.getKey( ), "#" ), displayName, rm.getDescriptionKey( ), description, rm.isReadOnly( ) );
+ } ).collect( Collectors.toList( ) );
+ }
+}
<context:annotation-config/>
<context:component-scan
- base-package="org.apache.archiva.rest.services,org.apache.archiva.redback.rest.services"/>
+ base-package="org.apache.archiva.rest.services,org.apache.archiva.redback.rest.services,org.apache.archiva.rest.v2"/>
<!-- CXF OpenApiFeature -->
<bean id="archivaOpenApiFeature" class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">
+++ /dev/null
-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 com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.PropertyNamingStrategy;
-import io.restassured.RestAssured;
-import io.restassured.builder.RequestSpecBuilder;
-import io.restassured.config.ObjectMapperConfig;
-import io.restassured.config.RestAssuredConfig;
-import io.restassured.path.json.mapper.factory.Jackson2ObjectMapperFactory;
-import io.restassured.response.Response;
-import io.restassured.specification.RequestSpecification;
-import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
-import org.apache.archiva.redback.rest.services.BaseSetup;
-import org.apache.archiva.redback.role.RoleManager;
-import org.apache.archiva.redback.role.RoleManagerException;
-import org.apache.archiva.redback.users.User;
-import org.apache.archiva.redback.users.UserManager;
-import org.apache.archiva.redback.users.UserManagerException;
-import org.apache.archiva.redback.users.UserNotFoundException;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.SystemUtils;
-import org.apache.cxf.transport.servlet.CXFServlet;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.session.SessionHandler;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.junit.jupiter.api.Tag;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.web.context.ContextLoaderListener;
-
-import java.lang.reflect.Type;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.time.LocalTime;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static io.restassured.RestAssured.*;
-import static io.restassured.http.ContentType.JSON;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-/**
- * Native REST tests do not use the JAX-RS client and can be used with a remote
- * REST API service. The tests
- *
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@Tag( "rest-native" )
-@Tag( "rest-v2" )
-public abstract class AbstractNativeRestServices
-{
- private AtomicReference<Path> projectDir = new AtomicReference<>();
- private AtomicReference<Path> appServerBase = new AtomicReference<>( );
- private AtomicReference<Path> basePath = new AtomicReference<>( );
-
- public static final int STOPPED = 0;
- public static final int STOPPING = 1;
- public static final int STARTING = 2;
- public static final int STARTED = 3;
- public static final int ERROR = 4;
- private final boolean startServer;
- private final String serverPort;
- private final String baseUri;
-
- private RequestSpecification requestSpec;
- protected Logger log = LoggerFactory.getLogger( getClass( ) );
-
- private static AtomicReference<Server> server = new AtomicReference<>( );
- private static AtomicReference<ServerConnector> serverConnector = new AtomicReference<>( );
- private static AtomicInteger serverStarted = new AtomicInteger( STOPPED );
- private UserManager userManager;
- private RoleManager roleManager;
-
- private final boolean remoteService;
-
- private String adminToken;
- private String adminRefreshToken;
-
-
- public AbstractNativeRestServices( )
- {
- this.startServer = BaseSetup.startServer( );
- this.serverPort = BaseSetup.getServerPort( );
- this.baseUri = BaseSetup.getBaseUri( );
-
- if ( startServer )
- {
- this.remoteService = false;
- } else {
- this.remoteService = true;
- }
- }
-
- protected abstract String getServicePath( );
-
- protected String getSpringConfigLocation( )
- {
- return "classpath*:META-INF/spring-context.xml,classpath:META-INF/spring-context-native-test.xml";
- }
-
- protected RequestSpecification getRequestSpec( )
- {
- return this.requestSpec;
- }
-
- protected String getContextRoot( )
- {
- return "/api";
- }
-
-
- protected String getServiceBasePath( )
- {
- return "/v2/archiva";
- }
-
- protected String getRedbackServiceBasePath( )
- {
- return "/v2/redback";
- }
-
-
- protected String getBasePath( )
- {
- return new StringBuilder( )
- .append( getContextRoot( ) )
- .append( getServiceBasePath( ) )
- .append( getServicePath( ) ).toString( );
- }
-
- /**
- * Returns the server that was started, or null if not initialized before.
- *
- * @return
- */
- public Server getServer( )
- {
- return this.server.get( );
- }
-
- public int getServerPort( )
- {
- ServerConnector connector = serverConnector.get( );
- if ( connector != null )
- {
- return connector.getLocalPort( );
- }
- else
- {
- return 0;
- }
- }
-
- /**
- * Returns true, if the server does exist and is running.
- *
- * @return true, if server does exist and is running.
- */
- public boolean isServerRunning( )
- {
- return serverStarted.get( ) == STARTED && this.server.get( ) != null && this.server.get( ).isRunning( );
- }
-
- private UserManager getUserManager( )
- {
- if ( this.userManager == null )
- {
- UserManager userManager = ContextLoaderListener.getCurrentWebApplicationContext( )
- .getBean( "userManager#default", UserManager.class );
- assertNotNull( userManager );
- this.userManager = userManager;
- }
- return this.userManager;
- }
-
- private RoleManager getRoleManager( )
- {
- if ( this.roleManager == null )
- {
- RoleManager roleManager = ContextLoaderListener.getCurrentWebApplicationContext( )
- .getBean( "roleManager", RoleManager.class );
- assertNotNull( roleManager );
- this.roleManager = roleManager;
- }
- return this.roleManager;
- }
-
- protected String getAdminPwd( )
- {
- return BaseSetup.getAdminPwd( );
- }
-
- protected String getAdminUser( )
- {
- return RedbackRoleConstants.ADMINISTRATOR_ACCOUNT_NAME;
- }
-
- private void setupAdminUser( ) throws UserManagerException, RoleManagerException
- {
-
- UserManager um = getUserManager( );
-
- User adminUser = null;
- try
- {
- adminUser = um.findUser( getAdminUser( ) );
- }
- catch ( UserNotFoundException e )
- {
- // ignore
- }
- adminUser = um.createUser( getAdminUser( ), "Administrator", "admin@local.home" );
- adminUser.setUsername( getAdminUser( ) );
- adminUser.setPassword( getAdminPwd( ) );
- adminUser.setFullName( "the admin user" );
- adminUser.setEmail( "toto@toto.fr" );
- adminUser.setPermanent( true );
- adminUser.setValidated( true );
- adminUser.setLocked( false );
- adminUser.setPasswordChangeRequired( false );
- if ( adminUser == null )
- {
- um.addUser( adminUser );
- }
- else
- {
- um.updateUser( adminUser, false );
- }
- getRoleManager( ).assignRole( "system-administrator", adminUser.getUsername( ) );
- }
-
- protected Path getProjectDirectory() {
- if ( projectDir.get()==null) {
- String propVal = System.getProperty("mvn.project.base.dir");
- Path newVal;
- if (StringUtils.isEmpty(propVal)) {
- newVal = Paths.get("").toAbsolutePath();
- } else {
- newVal = Paths.get(propVal).toAbsolutePath();
- }
- projectDir.compareAndSet(null, newVal);
- }
- return projectDir.get();
- }
-
- public Path getBasedir()
- {
- if (basePath.get()==null) {
- String baseDir = System.getProperty( "basedir" );
- final Path baseDirPath;
- if (StringUtils.isNotEmpty( baseDir )) {
- baseDirPath = Paths.get( baseDir );
- } else {
- baseDirPath = getProjectDirectory( );
- }
- basePath.compareAndSet( null, baseDirPath );
- }
- return basePath.get( );
- }
-
- Path getAppserverBase() {
- if (appServerBase.get()==null) {
- String basePath = System.getProperty( "appserver.base" );
- final Path appserverPath;
- if (StringUtils.isNotEmpty( basePath )) {
- appserverPath = Paths.get( basePath ).toAbsolutePath( );
- } else {
- appserverPath = getBasedir( ).resolve( "target" ).resolve( "appserver-base-" + LocalTime.now( ).toSecondOfDay( ) );
- }
- appServerBase.compareAndSet( null, appserverPath );
- }
- return appServerBase.get();
- }
-
- private void removeAppsubFolder( Path appServerBase, String folder )
- throws Exception
- {
- Path directory = appServerBase.resolve( folder );
- if ( Files.exists(directory) )
- {
- org.apache.archiva.common.utils.FileUtils.deleteDirectory( directory );
- }
- }
-
- public void startServer( )
- throws Exception
- {
- if ( serverStarted.compareAndSet( STOPPED, STARTING ) )
- {
- try
- {
- log.info( "Starting server" );
- Path appServerBase = getAppserverBase( );
-
- removeAppsubFolder(appServerBase, "jcr");
- removeAppsubFolder(appServerBase, "conf");
- removeAppsubFolder(appServerBase, "data");
-
-
- Server myServer = new Server( );
- this.server.set( myServer );
- this.serverConnector.set( new ServerConnector( myServer, new HttpConnectionFactory( ) ) );
- myServer.addConnector( serverConnector.get( ) );
-
- ServletHolder servletHolder = new ServletHolder( new CXFServlet( ) );
- ServletContextHandler context = new ServletContextHandler( ServletContextHandler.SESSIONS );
- context.setResourceBase( SystemUtils.JAVA_IO_TMPDIR );
- context.setSessionHandler( new SessionHandler( ) );
- context.addServlet( servletHolder, getContextRoot( ) + "/*" );
- context.setInitParameter( "contextConfigLocation", getSpringConfigLocation( ) );
- context.addEventListener( new ContextLoaderListener( ) );
-
- getServer( ).setHandler( context );
- getServer( ).start( );
-
- if ( log.isDebugEnabled( ) )
- {
- log.debug( "Jetty dump: {}", getServer( ).dump( ) );
- }
-
- setupAdminUser( );
- log.info( "Started server on port {}", getServerPort( ) );
- serverStarted.set( STARTED );
- }
- finally
- {
- // In case, if the last statement was not reached
- serverStarted.compareAndSet( STARTING, ERROR );
- }
- }
-
- }
-
- public void stopServer( )
- throws Exception
- {
- if ( this.serverStarted.compareAndSet( STARTED, STOPPING ) )
- {
- try
- {
- final Server myServer = getServer( );
- if ( myServer != null )
- {
- log.info( "Stopping server" );
- myServer.stop( );
- }
- serverStarted.set( STOPPED );
- }
- finally
- {
- serverStarted.compareAndSet( STOPPING, ERROR );
- }
- }
- else
- {
- log.error( "Server is not in STARTED state!" );
- }
- }
-
-
- protected void setupNative( ) throws Exception
- {
- if ( this.startServer )
- {
- startServer( );
- }
-
- if ( StringUtils.isNotEmpty( serverPort ) )
- {
- RestAssured.port = Integer.parseInt( serverPort );
- }
- else
- {
- RestAssured.port = getServerPort( );
- }
- if ( StringUtils.isNotEmpty( baseUri ) )
- {
- RestAssured.baseURI = baseUri;
- }
- else
- {
- RestAssured.baseURI = "http://localhost";
- }
- String basePath = getBasePath( );
- this.requestSpec = getRequestSpecBuilder( ).build( );
- RestAssured.basePath = basePath;
- RestAssured.config = RestAssuredConfig.config().objectMapperConfig(new ObjectMapperConfig().jackson2ObjectMapperFactory(
- ( cls, charset ) -> {
- ObjectMapper om = new ObjectMapper().findAndRegisterModules();
- om.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- om.setPropertyNamingStrategy( PropertyNamingStrategy.SNAKE_CASE );
- return om;
- }
- ));
- }
-
- protected RequestSpecBuilder getRequestSpecBuilder( ) {
- return getRequestSpecBuilder( null );
- }
-
- protected RequestSpecBuilder getRequestSpecBuilder( String basePath )
- {
- String myBasePath = basePath == null ? getBasePath( ) : basePath;
- return new RequestSpecBuilder( ).setBaseUri( baseURI )
- .setPort( port )
- .setBasePath( myBasePath )
- .addHeader( "Origin", RestAssured.baseURI + ":" + RestAssured.port );
- }
-
- protected RequestSpecBuilder getAuthRequestSpecBuilder( )
- {
- return new RequestSpecBuilder( ).setBaseUri( baseURI )
- .setPort( port )
- .setBasePath( new StringBuilder( )
- .append( getContextRoot( ) )
- .append( getRedbackServiceBasePath() ).append("/auth").toString() )
- .addHeader( "Origin", RestAssured.baseURI + ":" + RestAssured.port );
- }
-
- protected RequestSpecification getRequestSpec( String bearerToken )
- {
- return getRequestSpecBuilder( ).addHeader( "Authorization", "Bearer " + bearerToken ).build( );
- }
-
- protected RequestSpecification getRequestSpec( String bearerToken, String path)
- {
- return getRequestSpecBuilder( path ).addHeader( "Authorization", "Bearer " + bearerToken ).build( );
- }
-
- protected void shutdownNative( ) throws Exception
- {
- if (startServer)
- {
- stopServer( );
- }
- }
-
- protected org.apache.archiva.redback.rest.api.model.User addRemoteUser(String userid, String password, String fullName, String mail) {
-
- return null;
- }
-
- protected void initAdminToken() {
- Map<String, Object> jsonAsMap = new HashMap<>();
- jsonAsMap.put( "grant_type", "authorization_code" );
- jsonAsMap.put("user_id", getAdminUser());
- jsonAsMap.put("password", getAdminPwd() );
- Response result = given( ).spec( getAuthRequestSpecBuilder().build() )
- .contentType( JSON )
- .body( jsonAsMap )
- .when( ).post( "/authenticate").then( ).statusCode( 200 )
- .extract( ).response( );
- this.adminToken = result.body( ).jsonPath( ).getString( "access_token" );
- this.adminRefreshToken = result.body( ).jsonPath( ).getString( "refresh_token" );
- }
-
- protected String getUserToken(String userId, String password) {
- Map<String, Object> jsonAsMap = new HashMap<>();
- jsonAsMap.put( "grant_type", "authorization_code" );
- jsonAsMap.put("user_id", userId);
- jsonAsMap.put("password", password );
- Response result = given( ).spec( getAuthRequestSpecBuilder().build() )
- .contentType( JSON )
- .body( jsonAsMap )
- .when( ).post( "/authenticate").then( ).statusCode( 200 )
- .extract( ).response( );
- return result.body( ).jsonPath( ).getString( "access_token" );
- }
- protected String getAdminToken() {
- if (this.adminToken == null) {
- initAdminToken();
- }
- return this.adminToken;
- }
-
-
- protected String getAdminRefreshToken() {
- if (this.adminRefreshToken == null) {
- initAdminToken();
- }
- return this.adminRefreshToken;
- }
-
- public boolean isRemoteService() {
- return this.remoteService;
- }
-}
+++ /dev/null
-package org.apache.archiva.rest.services.v2;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.restassured.path.json.JsonPath;
-import io.restassured.response.Response;
-import io.restassured.response.ResponseBody;
-import org.apache.archiva.components.rest.model.PagedResult;
-import org.apache.archiva.components.rest.model.PropertyEntry;
-import org.apache.archiva.rest.api.model.v2.BeanInformation;
-import org.apache.archiva.rest.api.model.v2.CacheConfiguration;
-import org.apache.archiva.rest.api.model.v2.LdapConfiguration;
-import org.apache.archiva.rest.api.model.v2.MavenManagedRepository;
-import org.apache.archiva.rest.api.services.v2.RestConfiguration;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.MethodOrderer;
-import org.junit.jupiter.api.Order;
-import org.junit.jupiter.api.Tag;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-import org.junit.jupiter.api.TestMethodOrder;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static io.restassured.RestAssured.given;
-import static io.restassured.http.ContentType.JSON;
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@TestInstance( TestInstance.Lifecycle.PER_CLASS )
-@Tag( "rest-native" )
-@TestMethodOrder( MethodOrderer.OrderAnnotation.class )
-@DisplayName( "Native REST tests for V2 ManagedRepositoryService" )
-public class NativeMavenManagedRepositoryServiceTest extends AbstractNativeRestServices
-{
- @Override
- protected String getServicePath( )
- {
- return "/repositories/maven/managed";
- }
-
- @BeforeAll
- void setup( ) throws Exception
- {
- super.setupNative( );
- }
-
- @AfterAll
- void destroy( ) throws Exception
- {
- super.shutdownNative( );
- }
-
- @Test
- @Order( 1 )
- void testGetRepositories( )
- {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- JsonPath json = response.getBody( ).jsonPath( );
- assertEquals( 2, json.getInt( "pagination.total_count" ) );
- assertEquals( 0, json.getInt( "pagination.offset" ) );
- assertEquals( Integer.valueOf( RestConfiguration.DEFAULT_PAGE_LIMIT ), json.getInt( "pagination.limit" ) );
- List<MavenManagedRepository> repositories = json.getList( "data", MavenManagedRepository.class );
- assertEquals( "internal", repositories.get( 0 ).getId( ) );
- assertEquals( "snapshots", repositories.get( 1 ).getId( ) );
- }
-
-
-
-}
+++ /dev/null
-package org.apache.archiva.rest.services.v2;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.restassured.response.Response;
-import org.apache.archiva.components.rest.model.PagedResult;
-import org.apache.archiva.rest.api.model.v2.RepositoryGroup;
-import org.apache.archiva.rest.api.services.v2.ArchivaRestError;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.MethodOrderer;
-import org.junit.jupiter.api.Tag;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-import org.junit.jupiter.api.TestMethodOrder;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static io.restassured.RestAssured.given;
-import static io.restassured.http.ContentType.JSON;
-import static org.easymock.EasyMock.contains;
-import static org.hamcrest.Matchers.endsWith;
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@TestInstance( TestInstance.Lifecycle.PER_CLASS )
-@Tag( "rest-native" )
-@TestMethodOrder( MethodOrderer.Random.class )
-@DisplayName( "Native REST tests for V2 RepositoryGroupService" )
-public class NativeRepositoryGroupServiceTest extends AbstractNativeRestServices
-{
- @Override
- protected String getServicePath( )
- {
- return "/repository_groups";
- }
-
- @BeforeAll
- void setup( ) throws Exception
- {
- super.setupNative( );
- }
-
- @AfterAll
- void destroy( ) throws Exception
- {
- super.shutdownNative( );
- }
-
- @Test
- void testGetEmptyList( )
- {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- PagedResult result = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 0, result.getPagination( ).getTotalCount( ) );
-
- }
-
- @Test
- void testAddGroup( )
- {
- String token = getAdminToken( );
- try
- {
- Map<String, Object> jsonAsMap = new HashMap<>( );
- jsonAsMap.put( "id", "group_001" );
- jsonAsMap.put( "name", "group_001" );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .post( "" )
- .then( ).statusCode( 201 ).extract( ).response( );
- assertNotNull( response );
- RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
- assertNotNull( result );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 1, resultList.getPagination( ).getTotalCount( ) );
- } finally
- {
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .delete( "group_001" )
- .then( ).statusCode( 200 );
- }
- }
-
- @Test
- void testAddExistingGroup( )
- {
- String token = getAdminToken( );
- try
- {
- Map<String, Object> jsonAsMap = new HashMap<>( );
- jsonAsMap.put( "id", "group_001" );
- jsonAsMap.put( "name", "group_001" );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .post( "" )
- .prettyPeek()
- .then( ).statusCode( 201 ).extract( ).response( );
- assertNotNull( response );
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .redirects().follow( false )
- .body( jsonAsMap )
- .post( "" )
- .prettyPeek()
- .then( ).statusCode( 303 )
- .assertThat()
- .header( "Location", endsWith("group_001") ).extract( ).response( );
- } finally
- {
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .delete( "group_001" );
- }
- }
-
-
- @Test
- void testAddMultipleGroups( )
- {
- String token = getAdminToken( );
- List<String> groups = new ArrayList<>( );
- try
- {
- for ( int i=0; i<10; i++)
- {
- String groupName = String.format( "group_%03d", i );
- groups.add( groupName );
- Map<String, Object> jsonAsMap = new HashMap<>( );
- jsonAsMap.put( "id", groupName );
- jsonAsMap.put( "name", groupName );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .post( "" )
- .then( ).statusCode( 201 ).extract( ).response( );
- assertNotNull( response );
- RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
- assertNotNull( result );
- }
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 10, resultList.getPagination( ).getTotalCount( ) );
- } finally
- {
- for (String groupName : groups)
- {
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .delete( groupName );
- }
- }
- }
-
- @Test
- void testRemoveRepositoryGroup( )
- {
- String token = getAdminToken( );
- List<String> groups = new ArrayList<>( );
- try
- {
- for ( int i=0; i<10; i++)
- {
- String groupName = String.format( "group_%03d", i );
- groups.add( groupName );
- Map<String, Object> jsonAsMap = new HashMap<>( );
- jsonAsMap.put( "id", groupName );
- jsonAsMap.put( "name", groupName );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .post( "" )
- .then( ).statusCode( 201 ).extract( ).response( );
- assertNotNull( response );
- RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
- assertNotNull( result );
- }
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .delete( "group_001" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 9, resultList.getPagination( ).getTotalCount( ) );
-
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .delete( "group_005" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 8, resultList.getPagination( ).getTotalCount( ) );
-
- } finally
- {
- for (String groupName : groups)
- {
- if (!("group_001".equals(groupName) || "group_005".equals(groupName) ) )
- {
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .delete( groupName );
- }
- }
- }
- }
-
-
- @Test
- void testAddRepositoryToGroup( )
- {
- String token = getAdminToken( );
- try
- {
- Map<String, Object> jsonAsMap = new HashMap<>( );
- jsonAsMap.put( "id", "group_001" );
- jsonAsMap.put( "name", "group_001" );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .post( "" )
- .prettyPeek()
- .then( ).statusCode( 201 ).extract( ).response( );
- assertNotNull( response );
- RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
- assertNotNull( result );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 1, resultList.getPagination( ).getTotalCount( ) );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .put( "group_001/repositories/internal" )
- .prettyPeek()
- .then( ).statusCode( 200 ).extract( ).response( );
-
- assertNotNull( response );
- result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
- assertNotNull( result );
- assertEquals( 1, result.getRepositories( ).size( ) );
- assertTrue( result.getRepositories( ).contains( "internal" ) );
-
- } finally
- {
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .delete( "group_001" );
- }
- }
-
- @Test
- void testAddRepositoryToGroupIdempotency( )
- {
- String token = getAdminToken( );
- try
- {
- Map<String, Object> jsonAsMap = new HashMap<>( );
- jsonAsMap.put( "id", "group_001" );
- jsonAsMap.put( "name", "group_001" );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .post( "" )
- .prettyPeek()
- .then( ).statusCode( 201 ).extract( ).response( );
- assertNotNull( response );
- RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
- assertNotNull( result );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 1, resultList.getPagination( ).getTotalCount( ) );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .put( "group_001/repositories/internal" )
- .prettyPeek()
- .then( ).statusCode( 200 ).extract( ).response( );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .put( "group_001/repositories/internal" )
- .prettyPeek()
- .then( ).statusCode( 200 ).extract( ).response( );
-
- assertNotNull( response );
- result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
- assertNotNull( result );
- assertEquals( 1, result.getRepositories( ).size( ) );
- assertTrue( result.getRepositories( ).contains( "internal" ) );
-
- } finally
- {
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .delete( "group_001" )
- .then( ).statusCode( 200 );
- }
- }
-
-
- @Test
- void testRemoveRepositoryFromGroup( )
- {
- String token = getAdminToken( );
- try
- {
- Map<String, Object> jsonAsMap = new HashMap<>( );
- jsonAsMap.put( "id", "group_001" );
- jsonAsMap.put( "name", "group_001" );
- jsonAsMap.put( "repositories", Arrays.asList( "internal" ) );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .post( "" )
- .prettyPeek()
- .then( ).statusCode( 201 ).extract( ).response( );
- assertNotNull( response );
- RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
- assertNotNull( result );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 1, resultList.getPagination( ).getTotalCount( ) );
-
- assertNotNull( result.getRepositories( ) );
- assertEquals( 1, result.getRepositories( ).size( ) );
- assertTrue( result.getRepositories( ).contains( "internal" ) );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .delete( "group_001/repositories/internal" )
- .prettyPeek()
- .then( ).statusCode( 200 ).extract( ).response( );
-
- assertNotNull( response );
- result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
- assertNotNull( result );
- assertEquals( 0, result.getRepositories( ).size( ) );
-
- } finally
- {
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .delete( "group_001" )
- .then( ).statusCode( 200 );
- }
- }
-
- @Test
- void testRemoveRepositoryFromGroup404( )
- {
- String token = getAdminToken( );
- try
- {
- Map<String, Object> jsonAsMap = new HashMap<>( );
- jsonAsMap.put( "id", "group_001" );
- jsonAsMap.put( "name", "group_001" );
- jsonAsMap.put( "repositories", Arrays.asList( "internal" ) );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .post( "" )
- .prettyPeek()
- .then( ).statusCode( 201 ).extract( ).response( );
- assertNotNull( response );
- RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
- assertNotNull( result );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 1, resultList.getPagination( ).getTotalCount( ) );
-
- assertNotNull( result.getRepositories( ) );
- assertEquals( 1, result.getRepositories( ).size( ) );
- assertTrue( result.getRepositories( ).contains( "internal" ) );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .delete( "group_001/repositories/internalxx" )
- .prettyPeek()
- .then( ).statusCode( 404 ).extract( ).response( );
-
- assertNotNull( response );
- ArchivaRestError error = response.getBody( ).jsonPath( ).getObject( "", ArchivaRestError.class );
- assertNotNull( error );
- } finally
- {
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .delete( "group_001" );
- }
- }
-
-}
+++ /dev/null
-package org.apache.archiva.rest.services.v2;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.restassured.response.Response;
-import org.apache.archiva.components.rest.model.PagedResult;
-import org.apache.archiva.rest.api.model.v2.Repository;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.MethodOrderer;
-import org.junit.jupiter.api.Tag;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-import org.junit.jupiter.api.TestMethodOrder;
-
-import java.util.List;
-
-import static io.restassured.RestAssured.given;
-import static io.restassured.http.ContentType.JSON;
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@TestInstance( TestInstance.Lifecycle.PER_CLASS )
-@Tag( "rest-native" )
-@TestMethodOrder( MethodOrderer.Random.class )
-@DisplayName( "Native REST tests for V2 RepositoryService" )
-public class NativeRepositoryServiceTest extends AbstractNativeRestServices
-{
- @Override
- protected String getServicePath( )
- {
- return "/repositories";
- }
-
- @BeforeAll
- void setup( ) throws Exception
- {
- super.setupNative( );
- }
-
- @AfterAll
- void destroy( ) throws Exception
- {
- super.shutdownNative( );
- }
-
- @Test
- void testGetRepositories() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- PagedResult<Repository> repositoryPagedResult = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 3, repositoryPagedResult.getPagination( ).getTotalCount( ) );
- List<Repository> data = response.getBody( ).jsonPath( ).getList( "data", Repository.class );
- assertTrue( data.stream( ).anyMatch( p -> "central".equals( p.getId( ) ) ) );
- assertTrue( data.stream( ).anyMatch( p -> "internal".equals( p.getId( ) ) ) );
- assertTrue( data.stream( ).anyMatch( p -> "snapshots".equals( p.getId( ) ) ) );
- Repository snapshotRepo = data.stream( ).filter( p -> "snapshots".equals( p.getId( ) ) ).findFirst( ).get( );
- assertEquals( "Archiva Managed Snapshot Repository", snapshotRepo.getName( ) );
- assertEquals( "MAVEN", snapshotRepo.getType() );
- assertEquals( "managed", snapshotRepo.getCharacteristic() );
- assertEquals( "default", snapshotRepo.getLayout() );
- assertTrue( snapshotRepo.isScanned( ) );
- assertTrue( snapshotRepo.isIndex( ) );
-
- Repository centralRepo = data.stream( ).filter( p -> "central".equals( p.getId( ) ) ).findFirst( ).get( );
- assertEquals( "Central Repository", centralRepo.getName( ) );
- assertEquals( "MAVEN", centralRepo.getType() );
- assertEquals( "remote", centralRepo.getCharacteristic() );
- assertEquals( "default", centralRepo.getLayout() );
-
-
- }
-
- @Test
- void testGetFilteredRepositories() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .queryParam( "q", "central" )
- .get( "" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- PagedResult<Repository> repositoryPagedResult = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 1, repositoryPagedResult.getPagination( ).getTotalCount( ) );
- List<Repository> data = response.getBody( ).jsonPath( ).getList( "data", Repository.class );
- assertTrue( data.stream( ).anyMatch( p -> "central".equals( p.getId( ) ) ) );
- }
-
-
- @Test
- void getStatistics() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "managed/internal/statistics" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
-
- }
-
- @Test
- void scheduleScan() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .post( "managed/internal/scan/schedule" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
-
- }
-
- @Test
- void immediateScan() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .post( "managed/internal/scan/now" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
-
- }
-
- @Test
- void scanStatus() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "managed/internal/scan/status" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
-
- }
-
- @Test
- void scheduleIndexDownload() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .post( "remote/central/index/download/start" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- }
-
- @Test
- void getIndexDownloadList() {
- String token = getAdminToken( );
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .queryParam( "immediate", "true" )
- .post( "remote/central/index/download/start" )
- .then( ).statusCode( 200 ).extract( ).response( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "remote/index/downloads" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- List<String> downloads = response.getBody( ).jsonPath( ).getList( "", String.class );
- assertEquals( 1, downloads.size() );
- assertEquals( "central", downloads.get( 0 ) );
- }
-
-}
+++ /dev/null
-package org.apache.archiva.rest.services.v2;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.restassured.response.Response;
-import org.apache.archiva.components.rest.model.PagedResult;
-import org.apache.archiva.components.rest.model.PropertyEntry;
-import org.apache.archiva.rest.api.model.v2.BeanInformation;
-import org.apache.archiva.rest.api.model.v2.CacheConfiguration;
-import org.apache.archiva.rest.api.model.v2.LdapConfiguration;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.MethodOrderer;
-import org.junit.jupiter.api.Tag;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-import org.junit.jupiter.api.TestMethodOrder;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static io.restassured.RestAssured.given;
-import static io.restassured.http.ContentType.JSON;
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-@TestInstance( TestInstance.Lifecycle.PER_CLASS )
-@Tag( "rest-native" )
-@TestMethodOrder( MethodOrderer.Random.class )
-@DisplayName( "Native REST tests for V2 SecurityConfigurationService" )
-public class NativeSecurityConfigurationServiceTest extends AbstractNativeRestServices
-{
- @Override
- protected String getServicePath( )
- {
- return "/security";
- }
-
- @BeforeAll
- void setup( ) throws Exception
- {
- super.setupNative( );
- }
-
- @AfterAll
- void destroy( ) throws Exception
- {
- super.shutdownNative( );
- }
-
- @Test
- void testGetConfiguration() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "config" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- assertEquals( "jpa", response.getBody( ).jsonPath( ).getString( "active_user_managers[0]" ) );
- assertEquals( "jpa", response.getBody( ).jsonPath( ).getString( "active_rbac_managers[0]" ) );
- assertEquals( "memory", response.getBody( ).jsonPath( ).getString( "properties.\"authentication.jwt.keystoreType\"" ) );
- assertEquals("10",response.getBody( ).jsonPath( ).getString( "properties.\"security.policy.allowed.login.attempt\""));
- assertTrue( response.getBody( ).jsonPath( ).getBoolean( "user_cache_enabled" ) );
- assertFalse( response.getBody( ).jsonPath( ).getBoolean( "ldap_active" ) );
- }
-
- @Test
- void testGetConfigurationProperties() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "config/properties" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- PagedResult<PropertyEntry> result = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- List<PropertyEntry> propList = response.getBody( ).jsonPath( ).getList( "data", PropertyEntry.class );
- assertEquals( 10, result.getPagination( ).getLimit( ) );
- assertEquals( 0, result.getPagination( ).getOffset( ) );
- assertEquals( 47, result.getPagination( ).getTotalCount( ) );
- assertEquals( "authentication.jwt.keystoreType", propList.get( 0 ).getKey() );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .queryParam( "offset", "3" )
- .queryParam( "limit", "5" )
- .get( "config/properties" )
- .then( ).statusCode( 200 ).extract( ).response( );
-
- assertNotNull( response );
- result = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
- assertEquals( 5, result.getPagination( ).getLimit( ) );
- assertEquals( 47, result.getPagination( ).getTotalCount( ) );
- propList = response.getBody( ).jsonPath( ).getList( "data", PropertyEntry.class );
- assertEquals( "authentication.jwt.refreshLifetimeMs", propList.get( 0 ).getKey() );
- }
-
- @Test
- void testGetLdapConfiguration() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "config/ldap" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- assertEquals( "", response.getBody( ).jsonPath( ).get( "host_name" ) );
- assertEquals( 0, response.getBody( ).jsonPath( ).getMap( "properties" ).size( ) );
- }
-
-
- @Test
- void testUpdateLdapConfiguration() {
- String token = getAdminToken( );
- try
- {
- Map<String, Object> jsonMap = new HashMap<>( );
- jsonMap.put( "host_name", "localhost" );
- jsonMap.put( "port", 389 );
- jsonMap.put( "ssl_enabled", false );
- jsonMap.put( "writable", true );
- jsonMap.put( "base_dn", "dc=apache,dc=org" );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonMap )
- .put( "config/ldap" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "config/ldap" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- LdapConfiguration config = response.getBody( ).jsonPath( ).getObject( "", LdapConfiguration.class );
- assertEquals( "localhost", config.getHostName( ) );
- assertEquals( 389, config.getPort( ) );
- assertFalse( config.isSslEnabled( ) );
- assertTrue( config.isWritable( ) );
- assertEquals( "dc=apache,dc=org", config.getBaseDn( ) );
- } finally
- {
- Map<String, Object> jsonMap = new HashMap<>( );
- jsonMap.put( "host_name", "" );
- jsonMap.put( "port", -1 );
- jsonMap.put( "ssl_enabled", false );
- jsonMap.put( "base_dn", "" );
- jsonMap.put( "writable", false );
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonMap )
- .put( "config/ldap" )
- .then( ).statusCode( 200 );
-
- }
- }
-
-
- @Test
- void testGetCacheConfiguration() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "config/cache" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- }
-
- @Test
- void testUpdateCacheConfiguration() {
- String token = getAdminToken( );
-
- try
- {
- Map<String, Object> jsonMap = new HashMap<>( );
- jsonMap.put( "time_to_idle_seconds", 1600 );
- jsonMap.put( "time_to_live_seconds", 12000 );
- jsonMap.put( "max_entries_in_memory", 500 );
- jsonMap.put( "max_entries_on_disk", 400 );
-
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonMap )
- .put( "config/cache" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "config/cache" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- CacheConfiguration config = response.getBody( ).jsonPath( ).getObject( "", CacheConfiguration.class );
- assertEquals( 1600, config.getTimeToIdleSeconds( ) );
- assertEquals( 12000, config.getTimeToLiveSeconds( ) );
- assertEquals( 500, config.getMaxEntriesInMemory( ) );
- assertEquals( 400, config.getMaxEntriesOnDisk( ) );
- } finally
- {
- Map<String, Object> jsonMap = new HashMap<>( );
- jsonMap.put( "time_to_idle_seconds", 1800 );
- jsonMap.put( "time_to_live_seconds", 14400 );
- jsonMap.put( "max_entries_in_memory", 1000 );
- jsonMap.put( "max_entries_on_disk", 0 );
-
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonMap )
- .put( "config/cache" )
- .then( ).statusCode( 200 );
-
- }
- }
-
-
- @Test
- void testGetUserManagers() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "user_managers" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- List<BeanInformation> usrList = response.getBody( ).jsonPath( ).getList( "", BeanInformation.class );
- assertEquals( 2, usrList.size( ) );
- assertTrue( usrList.stream( ).anyMatch( bi -> "LDAP User Manager".equals( bi.getDisplayName( ) ) ) );
- assertTrue( usrList.stream( ).anyMatch( bi -> "Database User Manager".equals( bi.getDisplayName( ) ) ) );
- }
-
- @Test
- void testGetRbacManagers() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "rbac_managers" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- List<BeanInformation> rbacList = response.getBody( ).jsonPath( ).getList( "", BeanInformation.class );
- assertEquals( 2, rbacList.size( ) );
- assertTrue( rbacList.stream( ).anyMatch( bi -> "Database RBAC Manager".equals( bi.getDisplayName( ) ) ) );
- assertTrue( rbacList.stream( ).anyMatch( bi -> "LDAP RBAC Manager".equals( bi.getDisplayName( ) ) ) );
- }
-
- @Test
- void testUpdateConfiguration() {
- String token = getAdminToken( );
- try
- {
- Map<String, Object> jsonAsMap = new HashMap<>( );
- jsonAsMap.put( "active_user_managers", Arrays.asList( "jpa", "ldap" ) );
- jsonAsMap.put( "active_rbac_managers", Arrays.asList( "jpa" ) );
- jsonAsMap.put( "user_cache_enabled", false );
- jsonAsMap.put( "ldap_active", false );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .put( "config" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "config" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- assertEquals( 2, response.getBody( ).jsonPath( ).getList( "active_user_managers" ).size( ) );
- } finally
- {
- Map<String, Object> jsonAsMap = new HashMap<>( );
- jsonAsMap.put( "active_user_managers", Arrays.asList( "jpa" ) );
- jsonAsMap.put( "active_rbac_managers", Arrays.asList( "jpa" ) );
- jsonAsMap.put( "user_cache_enabled", true );
- jsonAsMap.put( "ldap_active", false );
- given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonAsMap )
- .put( "config" )
- .then( ).statusCode( 200 );
-
- }
-
- }
-
- @Test
- void testGetConfigProperty() {
- String token = getAdminToken( );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "config/properties/rest.csrffilter.absentorigin.deny" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- assertEquals( "true", response.getBody( ).jsonPath( ).getString( "value" ) );
- }
-
- @Test
- void testUpdateConfigProperty() {
- String token = getAdminToken( );
-
- try
- {
- Map<String, String> jsonMap = new HashMap<>( );
- jsonMap.put( "value", "false" );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonMap )
- .put( "config/properties/rest.csrffilter.absentorigin.deny" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
-
-
- response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .get( "config/properties/rest.csrffilter.absentorigin.deny" )
- .then( ).statusCode( 200 ).extract( ).response( );
- assertNotNull( response );
- assertEquals( "false", response.getBody( ).jsonPath( ).getString( "value" ) );
- } finally
- {
- Map<String, String> jsonMap = new HashMap<>( );
- jsonMap.put( "value", "true" );
- Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
- .when( )
- .body( jsonMap )
- .put( "config/properties/rest.csrffilter.absentorigin.deny" )
- .then( ).statusCode( 200 ).extract( ).response( );
- }
- }
-
-
-}
--- /dev/null
+package org.apache.archiva.rest.v2.svc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.PropertyNamingStrategy;
+import io.restassured.RestAssured;
+import io.restassured.builder.RequestSpecBuilder;
+import io.restassured.config.ObjectMapperConfig;
+import io.restassured.config.RestAssuredConfig;
+import io.restassured.path.json.mapper.factory.Jackson2ObjectMapperFactory;
+import io.restassured.response.Response;
+import io.restassured.specification.RequestSpecification;
+import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
+import org.apache.archiva.redback.rest.services.BaseSetup;
+import org.apache.archiva.redback.role.RoleManager;
+import org.apache.archiva.redback.role.RoleManagerException;
+import org.apache.archiva.redback.users.User;
+import org.apache.archiva.redback.users.UserManager;
+import org.apache.archiva.redback.users.UserManagerException;
+import org.apache.archiva.redback.users.UserNotFoundException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.SystemUtils;
+import org.apache.cxf.transport.servlet.CXFServlet;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.junit.jupiter.api.Tag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.context.ContextLoaderListener;
+
+import java.lang.reflect.Type;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalTime;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static io.restassured.RestAssured.*;
+import static io.restassured.http.ContentType.JSON;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * Native REST tests do not use the JAX-RS client and can be used with a remote
+ * REST API service. The tests
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Tag( "rest-native" )
+@Tag( "rest-v2" )
+public abstract class AbstractNativeRestServices
+{
+ private AtomicReference<Path> projectDir = new AtomicReference<>();
+ private AtomicReference<Path> appServerBase = new AtomicReference<>( );
+ private AtomicReference<Path> basePath = new AtomicReference<>( );
+
+ public static final int STOPPED = 0;
+ public static final int STOPPING = 1;
+ public static final int STARTING = 2;
+ public static final int STARTED = 3;
+ public static final int ERROR = 4;
+ private final boolean startServer;
+ private final String serverPort;
+ private final String baseUri;
+
+ private RequestSpecification requestSpec;
+ protected Logger log = LoggerFactory.getLogger( getClass( ) );
+
+ private static AtomicReference<Server> server = new AtomicReference<>( );
+ private static AtomicReference<ServerConnector> serverConnector = new AtomicReference<>( );
+ private static AtomicInteger serverStarted = new AtomicInteger( STOPPED );
+ private UserManager userManager;
+ private RoleManager roleManager;
+
+ private final boolean remoteService;
+
+ private String adminToken;
+ private String adminRefreshToken;
+
+
+ public AbstractNativeRestServices( )
+ {
+ this.startServer = BaseSetup.startServer( );
+ this.serverPort = BaseSetup.getServerPort( );
+ this.baseUri = BaseSetup.getBaseUri( );
+
+ if ( startServer )
+ {
+ this.remoteService = false;
+ } else {
+ this.remoteService = true;
+ }
+ }
+
+ protected abstract String getServicePath( );
+
+ protected String getSpringConfigLocation( )
+ {
+ return "classpath*:META-INF/spring-context.xml,classpath:META-INF/spring-context-native-test.xml";
+ }
+
+ protected RequestSpecification getRequestSpec( )
+ {
+ return this.requestSpec;
+ }
+
+ protected String getContextRoot( )
+ {
+ return "/api";
+ }
+
+
+ protected String getServiceBasePath( )
+ {
+ return "/v2/archiva";
+ }
+
+ protected String getRedbackServiceBasePath( )
+ {
+ return "/v2/redback";
+ }
+
+
+ protected String getBasePath( )
+ {
+ return new StringBuilder( )
+ .append( getContextRoot( ) )
+ .append( getServiceBasePath( ) )
+ .append( getServicePath( ) ).toString( );
+ }
+
+ /**
+ * Returns the server that was started, or null if not initialized before.
+ *
+ * @return
+ */
+ public Server getServer( )
+ {
+ return this.server.get( );
+ }
+
+ public int getServerPort( )
+ {
+ ServerConnector connector = serverConnector.get( );
+ if ( connector != null )
+ {
+ return connector.getLocalPort( );
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ /**
+ * Returns true, if the server does exist and is running.
+ *
+ * @return true, if server does exist and is running.
+ */
+ public boolean isServerRunning( )
+ {
+ return serverStarted.get( ) == STARTED && this.server.get( ) != null && this.server.get( ).isRunning( );
+ }
+
+ private UserManager getUserManager( )
+ {
+ if ( this.userManager == null )
+ {
+ UserManager userManager = ContextLoaderListener.getCurrentWebApplicationContext( )
+ .getBean( "userManager#default", UserManager.class );
+ assertNotNull( userManager );
+ this.userManager = userManager;
+ }
+ return this.userManager;
+ }
+
+ private RoleManager getRoleManager( )
+ {
+ if ( this.roleManager == null )
+ {
+ RoleManager roleManager = ContextLoaderListener.getCurrentWebApplicationContext( )
+ .getBean( "roleManager", RoleManager.class );
+ assertNotNull( roleManager );
+ this.roleManager = roleManager;
+ }
+ return this.roleManager;
+ }
+
+ protected String getAdminPwd( )
+ {
+ return BaseSetup.getAdminPwd( );
+ }
+
+ protected String getAdminUser( )
+ {
+ return RedbackRoleConstants.ADMINISTRATOR_ACCOUNT_NAME;
+ }
+
+ private void setupAdminUser( ) throws UserManagerException, RoleManagerException
+ {
+
+ UserManager um = getUserManager( );
+
+ User adminUser = null;
+ try
+ {
+ adminUser = um.findUser( getAdminUser( ) );
+ }
+ catch ( UserNotFoundException e )
+ {
+ // ignore
+ }
+ adminUser = um.createUser( getAdminUser( ), "Administrator", "admin@local.home" );
+ adminUser.setUsername( getAdminUser( ) );
+ adminUser.setPassword( getAdminPwd( ) );
+ adminUser.setFullName( "the admin user" );
+ adminUser.setEmail( "toto@toto.fr" );
+ adminUser.setPermanent( true );
+ adminUser.setValidated( true );
+ adminUser.setLocked( false );
+ adminUser.setPasswordChangeRequired( false );
+ if ( adminUser == null )
+ {
+ um.addUser( adminUser );
+ }
+ else
+ {
+ um.updateUser( adminUser, false );
+ }
+ getRoleManager( ).assignRole( "system-administrator", adminUser.getUsername( ) );
+ }
+
+ protected Path getProjectDirectory() {
+ if ( projectDir.get()==null) {
+ String propVal = System.getProperty("mvn.project.base.dir");
+ Path newVal;
+ if (StringUtils.isEmpty(propVal)) {
+ newVal = Paths.get("").toAbsolutePath();
+ } else {
+ newVal = Paths.get(propVal).toAbsolutePath();
+ }
+ projectDir.compareAndSet(null, newVal);
+ }
+ return projectDir.get();
+ }
+
+ public Path getBasedir()
+ {
+ if (basePath.get()==null) {
+ String baseDir = System.getProperty( "basedir" );
+ final Path baseDirPath;
+ if (StringUtils.isNotEmpty( baseDir )) {
+ baseDirPath = Paths.get( baseDir );
+ } else {
+ baseDirPath = getProjectDirectory( );
+ }
+ basePath.compareAndSet( null, baseDirPath );
+ }
+ return basePath.get( );
+ }
+
+ Path getAppserverBase() {
+ if (appServerBase.get()==null) {
+ String basePath = System.getProperty( "appserver.base" );
+ final Path appserverPath;
+ if (StringUtils.isNotEmpty( basePath )) {
+ appserverPath = Paths.get( basePath ).toAbsolutePath( );
+ } else {
+ appserverPath = getBasedir( ).resolve( "target" ).resolve( "appserver-base-" + LocalTime.now( ).toSecondOfDay( ) );
+ }
+ appServerBase.compareAndSet( null, appserverPath );
+ }
+ return appServerBase.get();
+ }
+
+ private void removeAppsubFolder( Path appServerBase, String folder )
+ throws Exception
+ {
+ Path directory = appServerBase.resolve( folder );
+ if ( Files.exists(directory) )
+ {
+ org.apache.archiva.common.utils.FileUtils.deleteDirectory( directory );
+ }
+ }
+
+ public void startServer( )
+ throws Exception
+ {
+ if ( serverStarted.compareAndSet( STOPPED, STARTING ) )
+ {
+ try
+ {
+ log.info( "Starting server" );
+ Path appServerBase = getAppserverBase( );
+
+ removeAppsubFolder(appServerBase, "jcr");
+ removeAppsubFolder(appServerBase, "conf");
+ removeAppsubFolder(appServerBase, "data");
+
+
+ Server myServer = new Server( );
+ this.server.set( myServer );
+ this.serverConnector.set( new ServerConnector( myServer, new HttpConnectionFactory( ) ) );
+ myServer.addConnector( serverConnector.get( ) );
+
+ ServletHolder servletHolder = new ServletHolder( new CXFServlet( ) );
+ ServletContextHandler context = new ServletContextHandler( ServletContextHandler.SESSIONS );
+ context.setResourceBase( SystemUtils.JAVA_IO_TMPDIR );
+ context.setSessionHandler( new SessionHandler( ) );
+ context.addServlet( servletHolder, getContextRoot( ) + "/*" );
+ context.setInitParameter( "contextConfigLocation", getSpringConfigLocation( ) );
+ context.addEventListener( new ContextLoaderListener( ) );
+
+ getServer( ).setHandler( context );
+ getServer( ).start( );
+
+ if ( log.isDebugEnabled( ) )
+ {
+ log.debug( "Jetty dump: {}", getServer( ).dump( ) );
+ }
+
+ setupAdminUser( );
+ log.info( "Started server on port {}", getServerPort( ) );
+ serverStarted.set( STARTED );
+ }
+ finally
+ {
+ // In case, if the last statement was not reached
+ serverStarted.compareAndSet( STARTING, ERROR );
+ }
+ }
+
+ }
+
+ public void stopServer( )
+ throws Exception
+ {
+ if ( this.serverStarted.compareAndSet( STARTED, STOPPING ) )
+ {
+ try
+ {
+ final Server myServer = getServer( );
+ if ( myServer != null )
+ {
+ log.info( "Stopping server" );
+ myServer.stop( );
+ }
+ serverStarted.set( STOPPED );
+ }
+ finally
+ {
+ serverStarted.compareAndSet( STOPPING, ERROR );
+ }
+ }
+ else
+ {
+ log.error( "Server is not in STARTED state!" );
+ }
+ }
+
+
+ protected void setupNative( ) throws Exception
+ {
+ if ( this.startServer )
+ {
+ startServer( );
+ }
+
+ if ( StringUtils.isNotEmpty( serverPort ) )
+ {
+ RestAssured.port = Integer.parseInt( serverPort );
+ }
+ else
+ {
+ RestAssured.port = getServerPort( );
+ }
+ if ( StringUtils.isNotEmpty( baseUri ) )
+ {
+ RestAssured.baseURI = baseUri;
+ }
+ else
+ {
+ RestAssured.baseURI = "http://localhost";
+ }
+ String basePath = getBasePath( );
+ this.requestSpec = getRequestSpecBuilder( ).build( );
+ RestAssured.basePath = basePath;
+ RestAssured.config = RestAssuredConfig.config().objectMapperConfig(new ObjectMapperConfig().jackson2ObjectMapperFactory(
+ ( cls, charset ) -> {
+ ObjectMapper om = new ObjectMapper().findAndRegisterModules();
+ om.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ om.setPropertyNamingStrategy( PropertyNamingStrategy.SNAKE_CASE );
+ return om;
+ }
+ ));
+ }
+
+ protected RequestSpecBuilder getRequestSpecBuilder( ) {
+ return getRequestSpecBuilder( null );
+ }
+
+ protected RequestSpecBuilder getRequestSpecBuilder( String basePath )
+ {
+ String myBasePath = basePath == null ? getBasePath( ) : basePath;
+ return new RequestSpecBuilder( ).setBaseUri( baseURI )
+ .setPort( port )
+ .setBasePath( myBasePath )
+ .addHeader( "Origin", RestAssured.baseURI + ":" + RestAssured.port );
+ }
+
+ protected RequestSpecBuilder getAuthRequestSpecBuilder( )
+ {
+ return new RequestSpecBuilder( ).setBaseUri( baseURI )
+ .setPort( port )
+ .setBasePath( new StringBuilder( )
+ .append( getContextRoot( ) )
+ .append( getRedbackServiceBasePath() ).append("/auth").toString() )
+ .addHeader( "Origin", RestAssured.baseURI + ":" + RestAssured.port );
+ }
+
+ protected RequestSpecification getRequestSpec( String bearerToken )
+ {
+ return getRequestSpecBuilder( ).addHeader( "Authorization", "Bearer " + bearerToken ).build( );
+ }
+
+ protected RequestSpecification getRequestSpec( String bearerToken, String path)
+ {
+ return getRequestSpecBuilder( path ).addHeader( "Authorization", "Bearer " + bearerToken ).build( );
+ }
+
+ protected void shutdownNative( ) throws Exception
+ {
+ if (startServer)
+ {
+ stopServer( );
+ }
+ }
+
+ protected org.apache.archiva.redback.rest.api.model.User addRemoteUser(String userid, String password, String fullName, String mail) {
+
+ return null;
+ }
+
+ protected void initAdminToken() {
+ Map<String, Object> jsonAsMap = new HashMap<>();
+ jsonAsMap.put( "grant_type", "authorization_code" );
+ jsonAsMap.put("user_id", getAdminUser());
+ jsonAsMap.put("password", getAdminPwd() );
+ Response result = given( ).spec( getAuthRequestSpecBuilder().build() )
+ .contentType( JSON )
+ .body( jsonAsMap )
+ .when( ).post( "/authenticate").then( ).statusCode( 200 )
+ .extract( ).response( );
+ this.adminToken = result.body( ).jsonPath( ).getString( "access_token" );
+ this.adminRefreshToken = result.body( ).jsonPath( ).getString( "refresh_token" );
+ }
+
+ protected String getUserToken(String userId, String password) {
+ Map<String, Object> jsonAsMap = new HashMap<>();
+ jsonAsMap.put( "grant_type", "authorization_code" );
+ jsonAsMap.put("user_id", userId);
+ jsonAsMap.put("password", password );
+ Response result = given( ).spec( getAuthRequestSpecBuilder().build() )
+ .contentType( JSON )
+ .body( jsonAsMap )
+ .when( ).post( "/authenticate").then( ).statusCode( 200 )
+ .extract( ).response( );
+ return result.body( ).jsonPath( ).getString( "access_token" );
+ }
+ protected String getAdminToken() {
+ if (this.adminToken == null) {
+ initAdminToken();
+ }
+ return this.adminToken;
+ }
+
+
+ protected String getAdminRefreshToken() {
+ if (this.adminRefreshToken == null) {
+ initAdminToken();
+ }
+ return this.adminRefreshToken;
+ }
+
+ public boolean isRemoteService() {
+ return this.remoteService;
+ }
+}
--- /dev/null
+package org.apache.archiva.rest.v2.svc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.restassured.path.json.JsonPath;
+import io.restassured.response.Response;
+import org.apache.archiva.rest.api.v2.model.MavenManagedRepository;
+import org.apache.archiva.rest.api.v2.svc.RestConfiguration;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import java.util.List;
+
+import static io.restassured.RestAssured.given;
+import static io.restassured.http.ContentType.JSON;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@TestInstance( TestInstance.Lifecycle.PER_CLASS )
+@Tag( "rest-native" )
+@TestMethodOrder( MethodOrderer.OrderAnnotation.class )
+@DisplayName( "Native REST tests for V2 ManagedRepositoryService" )
+public class NativeMavenManagedRepositoryServiceTest extends AbstractNativeRestServices
+{
+ @Override
+ protected String getServicePath( )
+ {
+ return "/repositories/maven/managed";
+ }
+
+ @BeforeAll
+ void setup( ) throws Exception
+ {
+ super.setupNative( );
+ }
+
+ @AfterAll
+ void destroy( ) throws Exception
+ {
+ super.shutdownNative( );
+ }
+
+ @Test
+ @Order( 1 )
+ void testGetRepositories( )
+ {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ JsonPath json = response.getBody( ).jsonPath( );
+ assertEquals( 2, json.getInt( "pagination.total_count" ) );
+ assertEquals( 0, json.getInt( "pagination.offset" ) );
+ assertEquals( Integer.valueOf( RestConfiguration.DEFAULT_PAGE_LIMIT ), json.getInt( "pagination.limit" ) );
+ List<MavenManagedRepository> repositories = json.getList( "data", MavenManagedRepository.class );
+ assertEquals( "internal", repositories.get( 0 ).getId( ) );
+ assertEquals( "snapshots", repositories.get( 1 ).getId( ) );
+ }
+
+
+
+}
--- /dev/null
+package org.apache.archiva.rest.v2.svc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.restassured.response.Response;
+import org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.rest.api.v2.model.RepositoryGroup;
+import org.apache.archiva.rest.api.v2.svc.ArchivaRestError;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static io.restassured.RestAssured.given;
+import static io.restassured.http.ContentType.JSON;
+import static org.hamcrest.Matchers.endsWith;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@TestInstance( TestInstance.Lifecycle.PER_CLASS )
+@Tag( "rest-native" )
+@TestMethodOrder( MethodOrderer.Random.class )
+@DisplayName( "Native REST tests for V2 RepositoryGroupService" )
+public class NativeRepositoryGroupServiceTest extends AbstractNativeRestServices
+{
+ @Override
+ protected String getServicePath( )
+ {
+ return "/repository_groups";
+ }
+
+ @BeforeAll
+ void setup( ) throws Exception
+ {
+ super.setupNative( );
+ }
+
+ @AfterAll
+ void destroy( ) throws Exception
+ {
+ super.shutdownNative( );
+ }
+
+ @Test
+ void testGetEmptyList( )
+ {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ PagedResult result = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 0, result.getPagination( ).getTotalCount( ) );
+
+ }
+
+ @Test
+ void testAddGroup( )
+ {
+ String token = getAdminToken( );
+ try
+ {
+ Map<String, Object> jsonAsMap = new HashMap<>( );
+ jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .post( "" )
+ .then( ).statusCode( 201 ).extract( ).response( );
+ assertNotNull( response );
+ RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
+ assertNotNull( result );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 1, resultList.getPagination( ).getTotalCount( ) );
+ } finally
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "group_001" )
+ .then( ).statusCode( 200 );
+ }
+ }
+
+ @Test
+ void testAddExistingGroup( )
+ {
+ String token = getAdminToken( );
+ try
+ {
+ Map<String, Object> jsonAsMap = new HashMap<>( );
+ jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .post( "" )
+ .prettyPeek()
+ .then( ).statusCode( 201 ).extract( ).response( );
+ assertNotNull( response );
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .redirects().follow( false )
+ .body( jsonAsMap )
+ .post( "" )
+ .prettyPeek()
+ .then( ).statusCode( 303 )
+ .assertThat()
+ .header( "Location", endsWith("group_001") ).extract( ).response( );
+ } finally
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "group_001" );
+ }
+ }
+
+
+ @Test
+ void testAddMultipleGroups( )
+ {
+ String token = getAdminToken( );
+ List<String> groups = new ArrayList<>( );
+ try
+ {
+ for ( int i=0; i<10; i++)
+ {
+ String groupName = String.format( "group_%03d", i );
+ groups.add( groupName );
+ Map<String, Object> jsonAsMap = new HashMap<>( );
+ jsonAsMap.put( "id", groupName );
+ jsonAsMap.put( "name", groupName );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .post( "" )
+ .then( ).statusCode( 201 ).extract( ).response( );
+ assertNotNull( response );
+ RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
+ assertNotNull( result );
+ }
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 10, resultList.getPagination( ).getTotalCount( ) );
+ } finally
+ {
+ for (String groupName : groups)
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( groupName );
+ }
+ }
+ }
+
+ @Test
+ void testRemoveRepositoryGroup( )
+ {
+ String token = getAdminToken( );
+ List<String> groups = new ArrayList<>( );
+ try
+ {
+ for ( int i=0; i<10; i++)
+ {
+ String groupName = String.format( "group_%03d", i );
+ groups.add( groupName );
+ Map<String, Object> jsonAsMap = new HashMap<>( );
+ jsonAsMap.put( "id", groupName );
+ jsonAsMap.put( "name", groupName );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .post( "" )
+ .then( ).statusCode( 201 ).extract( ).response( );
+ assertNotNull( response );
+ RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
+ assertNotNull( result );
+ }
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "group_001" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 9, resultList.getPagination( ).getTotalCount( ) );
+
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "group_005" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 8, resultList.getPagination( ).getTotalCount( ) );
+
+ } finally
+ {
+ for (String groupName : groups)
+ {
+ if (!("group_001".equals(groupName) || "group_005".equals(groupName) ) )
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( groupName );
+ }
+ }
+ }
+ }
+
+
+ @Test
+ void testAddRepositoryToGroup( )
+ {
+ String token = getAdminToken( );
+ try
+ {
+ Map<String, Object> jsonAsMap = new HashMap<>( );
+ jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .post( "" )
+ .prettyPeek()
+ .then( ).statusCode( 201 ).extract( ).response( );
+ assertNotNull( response );
+ RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
+ assertNotNull( result );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 1, resultList.getPagination( ).getTotalCount( ) );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .put( "group_001/repositories/internal" )
+ .prettyPeek()
+ .then( ).statusCode( 200 ).extract( ).response( );
+
+ assertNotNull( response );
+ result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
+ assertNotNull( result );
+ assertEquals( 1, result.getRepositories( ).size( ) );
+ assertTrue( result.getRepositories( ).contains( "internal" ) );
+
+ } finally
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "group_001" );
+ }
+ }
+
+ @Test
+ void testAddRepositoryToGroupIdempotency( )
+ {
+ String token = getAdminToken( );
+ try
+ {
+ Map<String, Object> jsonAsMap = new HashMap<>( );
+ jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .post( "" )
+ .prettyPeek()
+ .then( ).statusCode( 201 ).extract( ).response( );
+ assertNotNull( response );
+ RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
+ assertNotNull( result );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 1, resultList.getPagination( ).getTotalCount( ) );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .put( "group_001/repositories/internal" )
+ .prettyPeek()
+ .then( ).statusCode( 200 ).extract( ).response( );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .put( "group_001/repositories/internal" )
+ .prettyPeek()
+ .then( ).statusCode( 200 ).extract( ).response( );
+
+ assertNotNull( response );
+ result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
+ assertNotNull( result );
+ assertEquals( 1, result.getRepositories( ).size( ) );
+ assertTrue( result.getRepositories( ).contains( "internal" ) );
+
+ } finally
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "group_001" )
+ .then( ).statusCode( 200 );
+ }
+ }
+
+
+ @Test
+ void testRemoveRepositoryFromGroup( )
+ {
+ String token = getAdminToken( );
+ try
+ {
+ Map<String, Object> jsonAsMap = new HashMap<>( );
+ jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
+ jsonAsMap.put( "repositories", Arrays.asList( "internal" ) );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .post( "" )
+ .prettyPeek()
+ .then( ).statusCode( 201 ).extract( ).response( );
+ assertNotNull( response );
+ RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
+ assertNotNull( result );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 1, resultList.getPagination( ).getTotalCount( ) );
+
+ assertNotNull( result.getRepositories( ) );
+ assertEquals( 1, result.getRepositories( ).size( ) );
+ assertTrue( result.getRepositories( ).contains( "internal" ) );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .delete( "group_001/repositories/internal" )
+ .prettyPeek()
+ .then( ).statusCode( 200 ).extract( ).response( );
+
+ assertNotNull( response );
+ result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
+ assertNotNull( result );
+ assertEquals( 0, result.getRepositories( ).size( ) );
+
+ } finally
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "group_001" )
+ .then( ).statusCode( 200 );
+ }
+ }
+
+ @Test
+ void testRemoveRepositoryFromGroup404( )
+ {
+ String token = getAdminToken( );
+ try
+ {
+ Map<String, Object> jsonAsMap = new HashMap<>( );
+ jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
+ jsonAsMap.put( "repositories", Arrays.asList( "internal" ) );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .post( "" )
+ .prettyPeek()
+ .then( ).statusCode( 201 ).extract( ).response( );
+ assertNotNull( response );
+ RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
+ assertNotNull( result );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ PagedResult resultList = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 1, resultList.getPagination( ).getTotalCount( ) );
+
+ assertNotNull( result.getRepositories( ) );
+ assertEquals( 1, result.getRepositories( ).size( ) );
+ assertTrue( result.getRepositories( ).contains( "internal" ) );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .delete( "group_001/repositories/internalxx" )
+ .prettyPeek()
+ .then( ).statusCode( 404 ).extract( ).response( );
+
+ assertNotNull( response );
+ ArchivaRestError error = response.getBody( ).jsonPath( ).getObject( "", ArchivaRestError.class );
+ assertNotNull( error );
+ } finally
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "group_001" );
+ }
+ }
+
+}
--- /dev/null
+package org.apache.archiva.rest.v2.svc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.restassured.response.Response;
+import org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.rest.api.v2.model.Repository;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import java.util.List;
+
+import static io.restassured.RestAssured.given;
+import static io.restassured.http.ContentType.JSON;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@TestInstance( TestInstance.Lifecycle.PER_CLASS )
+@Tag( "rest-native" )
+@TestMethodOrder( MethodOrderer.Random.class )
+@DisplayName( "Native REST tests for V2 RepositoryService" )
+public class NativeRepositoryServiceTest extends AbstractNativeRestServices
+{
+ @Override
+ protected String getServicePath( )
+ {
+ return "/repositories";
+ }
+
+ @BeforeAll
+ void setup( ) throws Exception
+ {
+ super.setupNative( );
+ }
+
+ @AfterAll
+ void destroy( ) throws Exception
+ {
+ super.shutdownNative( );
+ }
+
+ @Test
+ void testGetRepositories() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ PagedResult<Repository> repositoryPagedResult = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 3, repositoryPagedResult.getPagination( ).getTotalCount( ) );
+ List<Repository> data = response.getBody( ).jsonPath( ).getList( "data", Repository.class );
+ assertTrue( data.stream( ).anyMatch( p -> "central".equals( p.getId( ) ) ) );
+ assertTrue( data.stream( ).anyMatch( p -> "internal".equals( p.getId( ) ) ) );
+ assertTrue( data.stream( ).anyMatch( p -> "snapshots".equals( p.getId( ) ) ) );
+ Repository snapshotRepo = data.stream( ).filter( p -> "snapshots".equals( p.getId( ) ) ).findFirst( ).get( );
+ assertEquals( "Archiva Managed Snapshot Repository", snapshotRepo.getName( ) );
+ assertEquals( "MAVEN", snapshotRepo.getType() );
+ assertEquals( "managed", snapshotRepo.getCharacteristic() );
+ assertEquals( "default", snapshotRepo.getLayout() );
+ assertTrue( snapshotRepo.isScanned( ) );
+ assertTrue( snapshotRepo.isIndex( ) );
+
+ Repository centralRepo = data.stream( ).filter( p -> "central".equals( p.getId( ) ) ).findFirst( ).get( );
+ assertEquals( "Central Repository", centralRepo.getName( ) );
+ assertEquals( "MAVEN", centralRepo.getType() );
+ assertEquals( "remote", centralRepo.getCharacteristic() );
+ assertEquals( "default", centralRepo.getLayout() );
+
+
+ }
+
+ @Test
+ void testGetFilteredRepositories() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .queryParam( "q", "central" )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ PagedResult<Repository> repositoryPagedResult = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 1, repositoryPagedResult.getPagination( ).getTotalCount( ) );
+ List<Repository> data = response.getBody( ).jsonPath( ).getList( "data", Repository.class );
+ assertTrue( data.stream( ).anyMatch( p -> "central".equals( p.getId( ) ) ) );
+ }
+
+
+ @Test
+ void getStatistics() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "managed/internal/statistics" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+
+ }
+
+ @Test
+ void scheduleScan() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .post( "managed/internal/scan/schedule" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+
+ }
+
+ @Test
+ void immediateScan() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .post( "managed/internal/scan/now" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+
+ }
+
+ @Test
+ void scanStatus() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "managed/internal/scan/status" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+
+ }
+
+ @Test
+ void scheduleIndexDownload() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .post( "remote/central/index/download/start" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ }
+
+ @Test
+ void getIndexDownloadList() {
+ String token = getAdminToken( );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .queryParam( "immediate", "true" )
+ .post( "remote/central/index/download/start" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "remote/index/downloads" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ List<String> downloads = response.getBody( ).jsonPath( ).getList( "", String.class );
+ assertEquals( 1, downloads.size() );
+ assertEquals( "central", downloads.get( 0 ) );
+ }
+
+}
--- /dev/null
+package org.apache.archiva.rest.v2.svc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.restassured.response.Response;
+import org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.components.rest.model.PropertyEntry;
+import org.apache.archiva.rest.api.v2.model.BeanInformation;
+import org.apache.archiva.rest.api.v2.model.CacheConfiguration;
+import org.apache.archiva.rest.api.v2.model.LdapConfiguration;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static io.restassured.RestAssured.given;
+import static io.restassured.http.ContentType.JSON;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@TestInstance( TestInstance.Lifecycle.PER_CLASS )
+@Tag( "rest-native" )
+@TestMethodOrder( MethodOrderer.Random.class )
+@DisplayName( "Native REST tests for V2 SecurityConfigurationService" )
+public class NativeSecurityConfigurationServiceTest extends AbstractNativeRestServices
+{
+ @Override
+ protected String getServicePath( )
+ {
+ return "/security";
+ }
+
+ @BeforeAll
+ void setup( ) throws Exception
+ {
+ super.setupNative( );
+ }
+
+ @AfterAll
+ void destroy( ) throws Exception
+ {
+ super.shutdownNative( );
+ }
+
+ @Test
+ void testGetConfiguration() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "config" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ assertEquals( "jpa", response.getBody( ).jsonPath( ).getString( "active_user_managers[0]" ) );
+ assertEquals( "jpa", response.getBody( ).jsonPath( ).getString( "active_rbac_managers[0]" ) );
+ assertEquals( "memory", response.getBody( ).jsonPath( ).getString( "properties.\"authentication.jwt.keystoreType\"" ) );
+ assertEquals("10",response.getBody( ).jsonPath( ).getString( "properties.\"security.policy.allowed.login.attempt\""));
+ assertTrue( response.getBody( ).jsonPath( ).getBoolean( "user_cache_enabled" ) );
+ assertFalse( response.getBody( ).jsonPath( ).getBoolean( "ldap_active" ) );
+ }
+
+ @Test
+ void testGetConfigurationProperties() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "config/properties" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ PagedResult<PropertyEntry> result = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ List<PropertyEntry> propList = response.getBody( ).jsonPath( ).getList( "data", PropertyEntry.class );
+ assertEquals( 10, result.getPagination( ).getLimit( ) );
+ assertEquals( 0, result.getPagination( ).getOffset( ) );
+ assertEquals( 47, result.getPagination( ).getTotalCount( ) );
+ assertEquals( "authentication.jwt.keystoreType", propList.get( 0 ).getKey() );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .queryParam( "offset", "3" )
+ .queryParam( "limit", "5" )
+ .get( "config/properties" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+
+ assertNotNull( response );
+ result = response.getBody( ).jsonPath( ).getObject( "", PagedResult.class );
+ assertEquals( 5, result.getPagination( ).getLimit( ) );
+ assertEquals( 47, result.getPagination( ).getTotalCount( ) );
+ propList = response.getBody( ).jsonPath( ).getList( "data", PropertyEntry.class );
+ assertEquals( "authentication.jwt.refreshLifetimeMs", propList.get( 0 ).getKey() );
+ }
+
+ @Test
+ void testGetLdapConfiguration() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "config/ldap" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ assertEquals( "", response.getBody( ).jsonPath( ).get( "host_name" ) );
+ assertEquals( 0, response.getBody( ).jsonPath( ).getMap( "properties" ).size( ) );
+ }
+
+
+ @Test
+ void testUpdateLdapConfiguration() {
+ String token = getAdminToken( );
+ try
+ {
+ Map<String, Object> jsonMap = new HashMap<>( );
+ jsonMap.put( "host_name", "localhost" );
+ jsonMap.put( "port", 389 );
+ jsonMap.put( "ssl_enabled", false );
+ jsonMap.put( "writable", true );
+ jsonMap.put( "base_dn", "dc=apache,dc=org" );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonMap )
+ .put( "config/ldap" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "config/ldap" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ LdapConfiguration config = response.getBody( ).jsonPath( ).getObject( "", LdapConfiguration.class );
+ assertEquals( "localhost", config.getHostName( ) );
+ assertEquals( 389, config.getPort( ) );
+ assertFalse( config.isSslEnabled( ) );
+ assertTrue( config.isWritable( ) );
+ assertEquals( "dc=apache,dc=org", config.getBaseDn( ) );
+ } finally
+ {
+ Map<String, Object> jsonMap = new HashMap<>( );
+ jsonMap.put( "host_name", "" );
+ jsonMap.put( "port", -1 );
+ jsonMap.put( "ssl_enabled", false );
+ jsonMap.put( "base_dn", "" );
+ jsonMap.put( "writable", false );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonMap )
+ .put( "config/ldap" )
+ .then( ).statusCode( 200 );
+
+ }
+ }
+
+
+ @Test
+ void testGetCacheConfiguration() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "config/cache" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ }
+
+ @Test
+ void testUpdateCacheConfiguration() {
+ String token = getAdminToken( );
+
+ try
+ {
+ Map<String, Object> jsonMap = new HashMap<>( );
+ jsonMap.put( "time_to_idle_seconds", 1600 );
+ jsonMap.put( "time_to_live_seconds", 12000 );
+ jsonMap.put( "max_entries_in_memory", 500 );
+ jsonMap.put( "max_entries_on_disk", 400 );
+
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonMap )
+ .put( "config/cache" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "config/cache" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ CacheConfiguration config = response.getBody( ).jsonPath( ).getObject( "", CacheConfiguration.class );
+ assertEquals( 1600, config.getTimeToIdleSeconds( ) );
+ assertEquals( 12000, config.getTimeToLiveSeconds( ) );
+ assertEquals( 500, config.getMaxEntriesInMemory( ) );
+ assertEquals( 400, config.getMaxEntriesOnDisk( ) );
+ } finally
+ {
+ Map<String, Object> jsonMap = new HashMap<>( );
+ jsonMap.put( "time_to_idle_seconds", 1800 );
+ jsonMap.put( "time_to_live_seconds", 14400 );
+ jsonMap.put( "max_entries_in_memory", 1000 );
+ jsonMap.put( "max_entries_on_disk", 0 );
+
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonMap )
+ .put( "config/cache" )
+ .then( ).statusCode( 200 );
+
+ }
+ }
+
+
+ @Test
+ void testGetUserManagers() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "user_managers" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ List<BeanInformation> usrList = response.getBody( ).jsonPath( ).getList( "", BeanInformation.class );
+ assertEquals( 2, usrList.size( ) );
+ assertTrue( usrList.stream( ).anyMatch( bi -> "LDAP User Manager".equals( bi.getDisplayName( ) ) ) );
+ assertTrue( usrList.stream( ).anyMatch( bi -> "Database User Manager".equals( bi.getDisplayName( ) ) ) );
+ }
+
+ @Test
+ void testGetRbacManagers() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "rbac_managers" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ List<BeanInformation> rbacList = response.getBody( ).jsonPath( ).getList( "", BeanInformation.class );
+ assertEquals( 2, rbacList.size( ) );
+ assertTrue( rbacList.stream( ).anyMatch( bi -> "Database RBAC Manager".equals( bi.getDisplayName( ) ) ) );
+ assertTrue( rbacList.stream( ).anyMatch( bi -> "LDAP RBAC Manager".equals( bi.getDisplayName( ) ) ) );
+ }
+
+ @Test
+ void testUpdateConfiguration() {
+ String token = getAdminToken( );
+ try
+ {
+ Map<String, Object> jsonAsMap = new HashMap<>( );
+ jsonAsMap.put( "active_user_managers", Arrays.asList( "jpa", "ldap" ) );
+ jsonAsMap.put( "active_rbac_managers", Arrays.asList( "jpa" ) );
+ jsonAsMap.put( "user_cache_enabled", false );
+ jsonAsMap.put( "ldap_active", false );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .put( "config" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "config" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ assertEquals( 2, response.getBody( ).jsonPath( ).getList( "active_user_managers" ).size( ) );
+ } finally
+ {
+ Map<String, Object> jsonAsMap = new HashMap<>( );
+ jsonAsMap.put( "active_user_managers", Arrays.asList( "jpa" ) );
+ jsonAsMap.put( "active_rbac_managers", Arrays.asList( "jpa" ) );
+ jsonAsMap.put( "user_cache_enabled", true );
+ jsonAsMap.put( "ldap_active", false );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonAsMap )
+ .put( "config" )
+ .then( ).statusCode( 200 );
+
+ }
+
+ }
+
+ @Test
+ void testGetConfigProperty() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "config/properties/rest.csrffilter.absentorigin.deny" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ assertEquals( "true", response.getBody( ).jsonPath( ).getString( "value" ) );
+ }
+
+ @Test
+ void testUpdateConfigProperty() {
+ String token = getAdminToken( );
+
+ try
+ {
+ Map<String, String> jsonMap = new HashMap<>( );
+ jsonMap.put( "value", "false" );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonMap )
+ .put( "config/properties/rest.csrffilter.absentorigin.deny" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+
+
+ response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "config/properties/rest.csrffilter.absentorigin.deny" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ assertEquals( "false", response.getBody( ).jsonPath( ).getString( "value" ) );
+ } finally
+ {
+ Map<String, String> jsonMap = new HashMap<>( );
+ jsonMap.put( "value", "true" );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .body( jsonMap )
+ .put( "config/properties/rest.csrffilter.absentorigin.deny" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ }
+ }
+
+
+}