You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by ma...@apache.org on 2021/01/19 08:36:30 UTC
[archiva] branch master updated (09ada16 -> b97724c)
This is an automated email from the ASF dual-hosted git repository.
martin_s pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git.
from 09ada16 Avoid Jetty's default directory listing settings in web.xml
new 0430422 Adding ldapfactory refresh after config update
new 3313a6c Adding list update after group assignment
new b97724c Refactoring exceptions and adding REST V2 service
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../archiva/admin/model/EntityExistsException.java | 78 +++++++
.../admin/model/EntityNotFoundException.java | 79 +++++++
.../admin/model/RepositoryAdminException.java | 88 +++++++
.../archiva/admin/model/beans/RepositoryGroup.java | 12 +
.../admin/model/group/RepositoryGroupAdmin.java | 12 +-
.../admin/model/error/AdminErrors.properties} | 9 +
.../group/DefaultRepositoryGroupAdmin.java | 38 +--
.../rest/api/model/v2/MergeConfiguration.java | 110 +++++++++
.../archiva/rest/api/model/v2/RepositoryGroup.java | 149 ++++++++++++
.../api/services/v2/RepositoryGroupService.java | 257 +++++++++++++++++++++
.../archiva/rest/api/services/v2/package-info.java | 102 ++++++++
.../services/v2/DefaultRepositoryGroupService.java | 214 +++++++++++++++++
.../v2/DefaultSecurityConfigurationService.java | 1 +
.../apache/archiva/rest/services/v2/ErrorKeys.java | 11 +
.../manage-roles-edit.component.html | 2 +-
.../manage-roles-edit.component.ts | 18 +-
16 files changed, 1158 insertions(+), 22 deletions(-)
create mode 100644 archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/EntityExistsException.java
create mode 100644 archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/EntityNotFoundException.java
copy archiva-modules/{archiva-web/archiva-rest/archiva-rest-services/src/main/resources/org/apache/archiva/rest/RestBundle_fr.properties => archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/resources/org/apache/archiva/admin/model/error/AdminErrors.properties} (50%)
create mode 100644 archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MergeConfiguration.java
create mode 100644 archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryGroup.java
create mode 100644 archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryGroupService.java
create mode 100644 archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/package-info.java
create mode 100644 archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryGroupService.java
[archiva] 02/03: Adding list update after group assignment
Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git
commit 3313a6cee8bc30e0a9b87c83998cfb219bce7306
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Sun Jan 17 19:43:34 2021 +0100
Adding list update after group assignment
---
.../manage-roles-edit/manage-roles-edit.component.html | 2 +-
.../manage-roles-edit/manage-roles-edit.component.ts | 18 +++++++++++++-----
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html
index 47ac7c0..13e387d 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html
@@ -293,7 +293,7 @@
<div class="invalid-feedback"
*ngIf="groupSearchFailed">{{'roles.edit.groupSearchFailed'|translate}}</div>
</div>
- <button class="btn btn-primary" (click)="assignGroupRole()">{{'roles.edit.assignButton'|translate}}</button>
+ <button class="btn btn-primary" id="addGroupButton" (click)="assignGroupRole()">{{'roles.edit.assignButton'|translate}}</button>
</form>
</ng-template>
</ngb-panel>
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts
index 59f8fea..6dac709 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts
@@ -20,11 +20,11 @@ import {AfterContentInit, Component, EventEmitter, OnInit, Output, ViewChild} fr
import {ActivatedRoute} from "@angular/router";
import {FormBuilder, Validators} from "@angular/forms";
import {RoleService} from "@app/services/role.service";
-import {catchError, concatAll, debounceTime, distinctUntilChanged, filter, map, switchMap, tap} from "rxjs/operators";
+import {catchError, concatAll, debounceTime, distinctUntilChanged, filter, map, startWith, switchMap, tap} from "rxjs/operators";
import {Role} from '@app/model/role';
import {ErrorResult} from "@app/model/error-result";
import {EditBaseComponent} from "@app/modules/shared/edit-base.component";
-import {EMPTY, forkJoin, Observable, of, zip} from 'rxjs';
+import {EMPTY, forkJoin, fromEvent, Observable, of, zip} from 'rxjs';
import {RoleUpdate} from "@app/model/role-update";
import {EntityService} from "@app/model/entity-service";
import {User} from '@app/model/user';
@@ -34,9 +34,10 @@ import {UserInfo} from '@app/model/user-info';
import {HttpResponse} from "@angular/common/http";
import {PaginatedEntitiesComponent} from "@app/modules/shared/paginated-entities/paginated-entities.component";
import {ToastService} from "@app/services/toast.service";
-import {GroupService} from "@app/services/group.service";
import {GroupMapping} from "@app/model/group-mapping";
import { Group } from '@app/model/group';
+import { ElementRef } from '@angular/core';
+import { GroupService } from '@app/services/group.service';
@Component({
selector: 'app-manage-roles-edit',
@@ -70,6 +71,8 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements
@Output()
roleIdEvent: EventEmitter<string> = new EventEmitter<string>(true);
+ groupAddEvent: EventEmitter<any> = new EventEmitter<any>(true);
+
private roleMappings$;
constructor(private route: ActivatedRoute, public roleService: RoleService, private userService: UserService,
@@ -255,7 +258,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements
switchMap(term =>
this.groupService.query( term, 0, 10).pipe(
tap(() => this.groupSearchFailed = false),
- map(pagedResult=>
+ map(( pagedResult : PagedResult<Group>) =>
pagedResult.data),
catchError(() => {
this.groupSearchFailed = true;
@@ -358,6 +361,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements
this.result = response.body;
this.showSuccess('roles.edit.success.assignGroup',{'role_id':this.editRole.id,'group_name':groupName})
this.groupSearchModel=''
+ this.groupAddEvent.emit(groupName);
});
}
}
@@ -366,7 +370,11 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements
getMappedGroups(roleId:string) : Observable<string[]> {
console.log("Get mapped groups "+roleId);
if (roleId!=null && roleId.length>0) {
- return this.groupService.getGroupMappings().pipe(
+ return this.groupAddEvent.pipe(
+ startWith(0),
+ switchMap(()=>
+ this.groupService.getGroupMappings()
+ ),
map((gMapArray: GroupMapping[]) => {
console.log("Array " + gMapArray + " - " + gMapArray.length);
let result = [];
[archiva] 01/03: Adding ldapfactory refresh after config update
Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git
commit 043042238ad847883e773636fbac57dde1ace36a
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Sun Jan 17 19:43:14 2021 +0100
Adding ldapfactory refresh after config update
---
.../archiva/rest/services/v2/DefaultSecurityConfigurationService.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultSecurityConfigurationService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultSecurityConfigurationService.java
index c8f9c60..dd9a3f8 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultSecurityConfigurationService.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultSecurityConfigurationService.java
@@ -442,6 +442,7 @@ public class DefaultSecurityConfigurationService implements SecurityConfiguratio
updateConfig( configuration, redbackRuntimeConfiguration );
redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration );
+ ldapConnectionFactory.initialize( );
}
catch ( RepositoryAdminException e )
{
[archiva] 03/03: Refactoring exceptions and adding REST V2 service
Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git
commit b97724c6a70b18f5667b45a20375ff550bd9015c
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Tue Jan 19 09:36:23 2021 +0100
Refactoring exceptions and adding REST V2 service
---
.../archiva/admin/model/EntityExistsException.java | 78 +++++++
.../admin/model/EntityNotFoundException.java | 79 +++++++
.../admin/model/RepositoryAdminException.java | 88 +++++++
.../archiva/admin/model/beans/RepositoryGroup.java | 12 +
.../admin/model/group/RepositoryGroupAdmin.java | 12 +-
.../admin/model/error/AdminErrors.properties | 27 +++
.../group/DefaultRepositoryGroupAdmin.java | 38 +--
.../rest/api/model/v2/MergeConfiguration.java | 110 +++++++++
.../archiva/rest/api/model/v2/RepositoryGroup.java | 149 ++++++++++++
.../api/services/v2/RepositoryGroupService.java | 257 +++++++++++++++++++++
.../archiva/rest/api/services/v2/package-info.java | 102 ++++++++
.../services/v2/DefaultRepositoryGroupService.java | 214 +++++++++++++++++
.../apache/archiva/rest/services/v2/ErrorKeys.java | 11 +
13 files changed, 1161 insertions(+), 16 deletions(-)
diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/EntityExistsException.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/EntityExistsException.java
new file mode 100644
index 0000000..9868427
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/EntityExistsException.java
@@ -0,0 +1,78 @@
+package org.apache.archiva.admin.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.
+ */
+
+/**
+ * This exception is thrown, if a entity that should be created, exists already.
+ * @author Martin Stockhammer <ma...@apache.org>
+ * @since 3.0
+ */
+public class EntityExistsException extends RepositoryAdminException
+{
+ private static final String KEY = "entity.exists";
+
+ public static EntityExistsException of(String... parameters) {
+ String message = getMessage( KEY, parameters );
+ return new EntityExistsException( message, parameters );
+ }
+
+ public EntityExistsException( String s, String... parameters )
+ {
+ super( s );
+ setKey( KEY );
+ setParameters( parameters );
+ }
+
+ public EntityExistsException( String s, String fieldName, String... parameters )
+ {
+ super( s, fieldName );
+ setKey( KEY );
+ setParameters( parameters );
+ }
+
+ public EntityExistsException( String message, Throwable cause, String... parameters )
+ {
+ super( message, cause );
+ setKey( KEY );
+ setParameters( parameters );
+ }
+
+ public EntityExistsException( String message, Throwable cause, String fieldName, String... parameters )
+ {
+ super( message, cause, fieldName );
+ setKey( KEY );
+ setParameters( parameters );
+ }
+}
diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/EntityNotFoundException.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/EntityNotFoundException.java
new file mode 100644
index 0000000..90bf82d
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/EntityNotFoundException.java
@@ -0,0 +1,79 @@
+package org.apache.archiva.admin.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.
+ */
+
+/**
+ * This exception is thrown, if a requested entity does not exist.
+ *
+ * @author Martin Stockhammer <ma...@apache.org>
+ * @since 3.0
+ */
+public class EntityNotFoundException extends RepositoryAdminException
+{
+ public static final String KEY = "entity.not_found";
+
+ public static EntityNotFoundException of(String... parameters) {
+ String message = getMessage( KEY, parameters );
+ return new EntityNotFoundException( message, parameters );
+ }
+
+ public EntityNotFoundException( String s, String... parameters )
+ {
+ super( s );
+ setKey( KEY );
+ setParameters( parameters );
+ }
+
+ public EntityNotFoundException( String s, String fieldName, String... parameters )
+ {
+ super( s, fieldName );
+ setKey( KEY );
+ setParameters( parameters );
+ }
+
+ public EntityNotFoundException( String message, Throwable cause, String... parameters )
+ {
+ super( message, cause );
+ setKey( KEY );
+ setParameters( parameters );
+ }
+
+ public EntityNotFoundException( String message, Throwable cause, String fieldName, String... parameters )
+ {
+ super( message, cause, fieldName );
+ setKey( KEY );
+ setParameters( parameters );
+ }
+}
diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/RepositoryAdminException.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/RepositoryAdminException.java
index 80f7770..c684c0e 100644
--- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/RepositoryAdminException.java
+++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/RepositoryAdminException.java
@@ -19,6 +19,12 @@ package org.apache.archiva.admin.model;
*/
+import org.apache.commons.lang3.StringUtils;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
/**
* @author Olivier Lamy
* @since 1.4-M1
@@ -27,6 +33,8 @@ public class RepositoryAdminException
extends Exception
{
+ private static final ResourceBundle bundle = ResourceBundle.getBundle( "org.apache.archiva.admin.model.error.AdminErrors", Locale.ROOT );
+
/**
* can return the field name of bean with issue
* can be <code>null</code>
@@ -34,6 +42,58 @@ public class RepositoryAdminException
*/
private String fieldName;
+ /**
+ * A unique identifier of this error
+ * @since 3.0
+ */
+ private String key;
+ private boolean keyExists = false;
+
+ /**
+ * Message parameters
+ */
+ String[] parameters = new String[0];
+
+
+ public static RepositoryAdminException ofKey(String key, String... params) {
+ String message = getMessage( key, params );
+ RepositoryAdminException ex = new RepositoryAdminException( message );
+ ex.setKey( key );
+ ex.setParameters( params );
+ return ex;
+ }
+
+ protected static String getMessage( String key, String[] params )
+ {
+ return MessageFormat.format( bundle.getString( key ), params );
+ }
+
+ public static RepositoryAdminException ofKey(String key, Throwable cause, String... params) {
+ String message = getMessage( key, params );
+ RepositoryAdminException ex = new RepositoryAdminException( message, cause );
+ ex.setKey( key );
+ ex.setParameters( params );
+ return ex;
+ }
+
+
+ public static RepositoryAdminException ofKeyAndField(String key, String fieldName, String... params) {
+ String message = getMessage( key, params );
+ RepositoryAdminException ex = new RepositoryAdminException( message, fieldName );
+ ex.setKey( key );
+ ex.setParameters( params );
+ return ex;
+ }
+
+ public static RepositoryAdminException ofKeyAndField(String key, Throwable cause, String fieldName, String... params) {
+ String message = getMessage( key, params );
+ RepositoryAdminException ex = new RepositoryAdminException( message, cause, fieldName );
+ ex.setKey( key );
+ ex.setFieldName( fieldName );
+ ex.setParameters( params );
+ return ex;
+ }
+
public RepositoryAdminException( String s )
{
super( s );
@@ -65,4 +125,32 @@ public class RepositoryAdminException
{
this.fieldName = fieldName;
}
+
+ public String getKey( )
+ {
+ return key;
+ }
+
+ public void setKey( String key )
+ {
+ this.keyExists=!StringUtils.isEmpty( key );
+ this.key = key;
+ }
+
+ public boolean keyExists() {
+ return this.keyExists;
+ }
+
+ public String[] getParameters( )
+ {
+ return parameters;
+ }
+
+ public void setParameters( String[] parameters )
+ {
+ if (parameters==null) {
+ this.parameters = new String[0];
+ }
+ this.parameters = parameters;
+ }
}
diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/RepositoryGroup.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/RepositoryGroup.java
index 74bafcd..d4c0041 100644
--- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/RepositoryGroup.java
+++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/beans/RepositoryGroup.java
@@ -59,6 +59,8 @@ public class RepositoryGroup
*/
private String cronExpression;
+ private String location;
+
public RepositoryGroup()
{
// no op
@@ -184,6 +186,16 @@ public class RepositoryGroup
return this;
}
+ public String getLocation( )
+ {
+ return location;
+ }
+
+ public void setLocation( String location )
+ {
+ this.location = location;
+ }
+
@Override
public boolean equals( Object other )
{
diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/group/RepositoryGroupAdmin.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/group/RepositoryGroupAdmin.java
index e98e832..e5411fe 100644
--- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/group/RepositoryGroupAdmin.java
+++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/group/RepositoryGroupAdmin.java
@@ -19,6 +19,7 @@ package org.apache.archiva.admin.model.group;
*/
import org.apache.archiva.admin.model.AuditInformation;
+import org.apache.archiva.admin.model.EntityNotFoundException;
import org.apache.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.beans.RepositoryGroup;
import org.apache.archiva.repository.storage.StorageAsset;
@@ -35,8 +36,17 @@ public interface RepositoryGroupAdmin
List<RepositoryGroup> getRepositoriesGroups()
throws RepositoryAdminException;
+ /**
+ * Returns the repository group. If it is not found a {@link org.apache.archiva.admin.model.EntityNotFoundException}
+ * will be thrown.
+ *
+ * @param repositoryGroupId the identifier of the repository group
+ * @return the repository group object
+ * @throws RepositoryAdminException
+ * @throws EntityNotFoundException
+ */
RepositoryGroup getRepositoryGroup( String repositoryGroupId )
- throws RepositoryAdminException;
+ throws RepositoryAdminException, EntityNotFoundException;
Boolean addRepositoryGroup( RepositoryGroup repositoryGroup, AuditInformation auditInformation )
throws RepositoryAdminException;
diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/resources/org/apache/archiva/admin/model/error/AdminErrors.properties b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/resources/org/apache/archiva/admin/model/error/AdminErrors.properties
new file mode 100644
index 0000000..7a9ddf8
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/resources/org/apache/archiva/admin/model/error/AdminErrors.properties
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+
+entity.exists=The entity {0} exists already
+entity.not_found=The entity {0} was not found
+repository_group.id.empty=The repository group id was empty
+repository_group.id.max_length=The id "{0}" of the repository group exceeds {1} characters
+repository_group.id.invalid_chars=The repository group id "{0}" contains invalid characters. Only the following are allowed: {1}.
+repository_group.merged_index_ttl.min=Merged Index TTL must be greater than {0}.
+repository_group.repository.not_found=The member repository with id "{0}" does not exist. Cannot be used in a repository group.
+repository_group.registry.add_error=The registry could not add the repository "{0}": {1}
+repository_group.registry.update_error=The registry could not update the repository "{0}": {1}
diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/group/DefaultRepositoryGroupAdmin.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/group/DefaultRepositoryGroupAdmin.java
index 1986c42..3b810c7 100644
--- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/group/DefaultRepositoryGroupAdmin.java
+++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/group/DefaultRepositoryGroupAdmin.java
@@ -19,6 +19,8 @@ package org.apache.archiva.admin.repository.group;
*/
import org.apache.archiva.admin.model.AuditInformation;
+import org.apache.archiva.admin.model.EntityExistsException;
+import org.apache.archiva.admin.model.EntityNotFoundException;
import org.apache.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.beans.ManagedRepository;
import org.apache.archiva.admin.model.beans.RepositoryGroup;
@@ -125,8 +127,14 @@ public class DefaultRepositoryGroupAdmin
}
@Override
- public RepositoryGroup getRepositoryGroup( String repositoryGroupId ) {
- return convertRepositoryGroupObject( repositoryRegistry.getRepositoryGroup( repositoryGroupId ) );
+ public RepositoryGroup getRepositoryGroup( String repositoryGroupId ) throws EntityNotFoundException
+ {
+ org.apache.archiva.repository.RepositoryGroup group = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
+ if (group==null) {
+ throw new EntityNotFoundException( "Repository group does not exist" );
+ } else {
+ return convertRepositoryGroupObject( group );
+ }
}
@Override
@@ -146,7 +154,8 @@ public class DefaultRepositoryGroupAdmin
try {
repositoryRegistry.putRepositoryGroup(repositoryGroupConfiguration);
} catch (RepositoryException e) {
- e.printStackTrace();
+ log.error( "Could not add the repository group to the registry: {}", e.getMessage( ), e );
+ throw RepositoryAdminException.ofKey( "repository_group.registry.add_error", e, repositoryGroup.getId(), e.getMessage() );
}
triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.ADD_REPO_GROUP, auditInformation );
@@ -200,7 +209,8 @@ public class DefaultRepositoryGroupAdmin
try {
repositoryRegistry.putRepositoryGroup(repositoryGroupConfiguration);
} catch (RepositoryException e) {
- e.printStackTrace();
+ log.error( "Could not update the repository group in the registry: {}", e.getMessage( ), e );
+ throw RepositoryAdminException.ofKey( "repository_group.registry.update_error", e, repositoryGroup.getId(), e.getMessage() );
}
org.apache.archiva.repository.RepositoryGroup rg = repositoryRegistry.getRepositoryGroup( repositoryGroup.getId( ) );
@@ -349,26 +359,24 @@ public class DefaultRepositoryGroupAdmin
String repoGroupId = repositoryGroup.getId();
if ( StringUtils.isBlank( repoGroupId ) )
{
- throw new RepositoryAdminException( "repositoryGroup id cannot be empty" );
+ throw RepositoryAdminException.ofKey("repository_group.id.empty" );
}
if ( repoGroupId.length() > 100 )
{
- throw new RepositoryAdminException(
- "Identifier [" + repoGroupId + "] is over the maximum limit of 100 characters" );
+ throw RepositoryAdminException.ofKey("repository_group.id.max_length",repoGroupId, Integer.toString( 100 ));
}
Matcher matcher = REPO_GROUP_ID_PATTERN.matcher( repoGroupId );
if ( !matcher.matches() )
{
- throw new RepositoryAdminException(
- "Invalid character(s) found in identifier. Only the following characters are allowed: alphanumeric, '.', '-' and '_'" );
+ throw RepositoryAdminException.ofKey("repository_group.id.invalid_chars","alphanumeric, '.', '-','_'" );
}
if ( repositoryGroup.getMergedIndexTtl() <= 0 )
{
- throw new RepositoryAdminException( "Merged Index TTL must be greater than 0." );
+ throw RepositoryAdminException.ofKey("repository_group.merged_index_ttl.min","0" );
}
Configuration configuration = getArchivaConfiguration().getConfiguration();
@@ -377,18 +385,18 @@ public class DefaultRepositoryGroupAdmin
{
if ( !updateMode )
{
- throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId
+ throw new EntityExistsException( "Unable to add new repository group with id [" + repoGroupId
+ "], that id already exists as a repository group." );
}
}
else if ( configuration.getManagedRepositoriesAsMap().containsKey( repoGroupId ) )
{
- throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId
+ throw new EntityExistsException( "Unable to add new repository group with id [" + repoGroupId
+ "], that id already exists as a managed repository." );
}
else if ( configuration.getRemoteRepositoriesAsMap().containsKey( repoGroupId ) )
{
- throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId
+ throw new EntityExistsException( "Unable to add new repository group with id [" + repoGroupId
+ "], that id already exists as a remote repository." );
}
@@ -402,8 +410,7 @@ public class DefaultRepositoryGroupAdmin
{
if ( getManagedRepositoryAdmin().getManagedRepository( id ) == null )
{
- throw new RepositoryAdminException(
- "managedRepository with id " + id + " not exists so cannot be used in a repositoryGroup" );
+ throw RepositoryAdminException.ofKey("repository_group.repository.not_found",id );
}
}
}
@@ -427,6 +434,7 @@ public class DefaultRepositoryGroupAdmin
}
rg.setCronExpression( group.getSchedulingDefinition() );
rg.setMergedIndexTtl( group.getMergedIndexTTL() );
+ rg.setLocation( group.getLocation().toString() );
return rg;
}
}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MergeConfiguration.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MergeConfiguration.java
new file mode 100644
index 0000000..c5e60da
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/MergeConfiguration.java
@@ -0,0 +1,110 @@
+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.Objects;
+
+import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_INDEX_PATH;
+
+/**
+ * Index merge configuration.
+ *
+ * @author Martin Stockhammer <ma...@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( );
+ }
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryGroup.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryGroup.java
new file mode 100644
index 0000000..d550f27
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/v2/RepositoryGroup.java
@@ -0,0 +1,149 @@
+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.Objects;
+
+/**
+ * @author Martin Stockhammer <ma...@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 final 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.admin.model.beans.RepositoryGroup modelObj ) {
+ RepositoryGroup result = new RepositoryGroup( );
+ MergeConfiguration mergeConfig = new MergeConfiguration( );
+ result.setMergeConfiguration( mergeConfig );
+ result.setId( modelObj.getId() );
+ result.setLocation( modelObj.getLocation() );
+ result.setRepositories( modelObj.getRepositories() );
+ mergeConfig.setMergedIndexPath( modelObj.getMergedIndexPath() );
+ mergeConfig.setMergedIndexTtlMinutes( modelObj.getMergedIndexTtl( ) );
+ mergeConfig.setIndexMergeSchedule( modelObj.getCronExpression( ) );
+ 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.clear();
+ this.repositories.addAll( 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;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ RepositoryGroup that = (RepositoryGroup) o;
+
+ if ( !Objects.equals( id, that.id ) ) return false;
+ if ( !repositories.equals( that.repositories ) )
+ return false;
+ if ( !Objects.equals( location, that.location ) ) return false;
+ return Objects.equals( mergeConfiguration, that.mergeConfiguration );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = id != null ? id.hashCode( ) : 0;
+ result = 31 * result + repositories.hashCode( );
+ result = 31 * result + ( location != null ? location.hashCode( ) : 0 );
+ result = 31 * result + ( mergeConfiguration != null ? mergeConfiguration.hashCode( ) : 0 );
+ return result;
+ }
+
+ @SuppressWarnings( "StringBufferReplaceableByString" )
+ @Override
+ public String toString( )
+ {
+ final StringBuilder sb = new StringBuilder( "RepositoryGroup{" );
+ sb.append( "id='" ).append( id ).append( '\'' );
+ sb.append( ", repositories=" ).append( repositories );
+ sb.append( ", location='" ).append( location ).append( '\'' );
+ sb.append( ", mergeConfiguration=" ).append( mergeConfiguration );
+ sb.append( '}' );
+ return sb.toString( );
+ }
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryGroupService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryGroupService.java
new file mode 100644
index 0000000..7796d1c
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/RepositoryGroupService.java
@@ -0,0 +1,257 @@
+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.Configuration.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( "key" ) List<String> orderBy,
+ @QueryParam("order") @DefaultValue( "asc" ) String order)
+ throws ArchivaRestServiceException;
+
+ @Path( "{repositoryGroupId}" )
+ @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( "repositoryGroupId" ) 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 list could be returned",
+ 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( "{repositoryGroupId}" )
+ @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( "repositoryGroupId" ) String groupId, RepositoryGroup repositoryGroup )
+ throws ArchivaRestServiceException;
+
+ @Path( "{repositoryGroupId}" )
+ @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( "repositoryGroupId" ) String repositoryGroupId )
+ throws ArchivaRestServiceException;
+
+ @Path( "{repositoryGroupId}/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( "repositoryGroupId" ) String repositoryGroupId,
+ @PathParam( "repositoryId" ) String repositoryId )
+ throws ArchivaRestServiceException;
+
+ @Path( "{repositoryGroupId}/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 = "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( "repositoryGroupId" ) String repositoryGroupId,
+ @PathParam( "repositoryId" ) String repositoryId )
+ throws ArchivaRestServiceException;
+
+
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/package-info.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/package-info.java
new file mode 100644
index 0000000..0cd02b0
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/v2/package-info.java
@@ -0,0 +1,102 @@
+/*
+ * 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 <ma...@apache.org>
+ * @since 3.0
+ */
+package org.apache.archiva.rest.api.services.v2;
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryGroupService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryGroupService.java
new file mode 100644
index 0000000..1855ea8
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/DefaultRepositoryGroupService.java
@@ -0,0 +1,214 @@
+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.EntityExistsException;
+import org.apache.archiva.admin.model.EntityNotFoundException;
+import org.apache.archiva.admin.model.RepositoryAdminException;
+import org.apache.archiva.admin.model.group.RepositoryGroupAdmin;
+import org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.components.rest.util.PagingHelper;
+import org.apache.archiva.components.rest.util.QueryHelper;
+import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal;
+import org.apache.archiva.redback.rest.services.RedbackRequestInformation;
+import org.apache.archiva.redback.users.User;
+import org.apache.archiva.rest.api.model.v2.RepositoryGroup;
+import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
+import org.apache.archiva.rest.api.services.v2.ErrorMessage;
+import org.apache.archiva.rest.api.services.v2.RepositoryGroupService;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+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.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * REST V2 Implementation for repository groups.
+ *
+ * @author Martin Stockhammer <ma...@apache.org>
+ * @since 3.0
+ * @see RepositoryGroupService
+ */
+public class DefaultRepositoryGroupService implements RepositoryGroupService
+{
+ @Context
+ HttpServletResponse httpServletResponse;
+
+ @Context
+ UriInfo uriInfo;
+
+ private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryGroupService.class );
+
+ private static final QueryHelper<org.apache.archiva.admin.model.beans.RepositoryGroup> QUERY_HELPER = new QueryHelper( new String[]{"id"} );
+ private static final PagingHelper PROP_PAGING_HELPER = new PagingHelper( );
+
+ @Inject
+ private RepositoryGroupAdmin repositoryGroupAdmin;
+
+
+ static
+ {
+ QUERY_HELPER.addStringFilter( "id", org.apache.archiva.admin.model.beans.RepositoryGroup::getId );
+ QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.admin.model.beans.RepositoryGroup::getId );
+ }
+
+
+ protected AuditInformation getAuditInformation()
+ {
+ RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
+ User user = redbackRequestInformation == null ? null : redbackRequestInformation.getUser();
+ String remoteAddr = redbackRequestInformation == null ? null : redbackRequestInformation.getRemoteAddr();
+ return new AuditInformation( user, remoteAddr );
+ }
+
+ @Override
+ public PagedResult<RepositoryGroup> getRepositoriesGroups( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ Predicate<org.apache.archiva.admin.model.beans.RepositoryGroup> filter = QUERY_HELPER.getQueryFilter( searchTerm );
+ Comparator<org.apache.archiva.admin.model.beans.RepositoryGroup> ordering = QUERY_HELPER.getComparator( orderBy, QUERY_HELPER.isAscending( order ) );
+ int totalCount = Math.toIntExact( repositoryGroupAdmin.getRepositoriesGroups( ).stream( ).filter( filter ).count( ) );
+ List<RepositoryGroup> result = repositoryGroupAdmin.getRepositoriesGroups( ).stream( ).filter( filter ).sorted( ordering ).skip( offset ).limit( limit ).map(
+ RepositoryGroup::of
+ ).collect( Collectors.toList( ) );
+ return new PagedResult<>( totalCount, offset, limit, result );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ log.error( "Repository admin error: {}", e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage() ) );
+ } 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
+ {
+ try
+ {
+ org.apache.archiva.admin.model.beans.RepositoryGroup group = repositoryGroupAdmin.getRepositoryGroup( repositoryGroupId );
+ return RepositoryGroup.of( group );
+ }
+ catch ( EntityNotFoundException e ) {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_EXIST, repositoryGroupId ), 404 );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage() ));
+ }
+ }
+
+ private org.apache.archiva.admin.model.beans.RepositoryGroup toModel( RepositoryGroup group) {
+ org.apache.archiva.admin.model.beans.RepositoryGroup result = new org.apache.archiva.admin.model.beans.RepositoryGroup( );
+ result.setId( group.getId( ) );
+ result.setLocation( group.getLocation( ) );
+ result.setRepositories( new ArrayList<>( group.getRepositories( ) ) );
+ result.setMergedIndexPath( group.getMergeConfiguration().getMergedIndexPath() );
+ result.setMergedIndexTtl( group.getMergeConfiguration().getMergedIndexTtlMinutes() );
+ result.setCronExpression( group.getMergeConfiguration().getIndexMergeSchedule() );
+ return result;
+ }
+
+ @Override
+ public RepositoryGroup addRepositoryGroup( RepositoryGroup repositoryGroup ) throws ArchivaRestServiceException
+ {
+ try
+ {
+ Boolean result = repositoryGroupAdmin.addRepositoryGroup( toModel( repositoryGroup ), getAuditInformation( ) );
+ if (result) {
+ org.apache.archiva.admin.model.beans.RepositoryGroup newGroup = repositoryGroupAdmin.getRepositoryGroup( repositoryGroup.getId( ) );
+ if (newGroup!=null) {
+ return RepositoryGroup.of( newGroup );
+ } else {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_ADD_FAILED ) );
+ }
+ } else {
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_ADD_FAILED ) );
+ }
+ } catch ( EntityExistsException e ) {
+ httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder( ).path( repositoryGroup.getId() ).build( ).toString( ) );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_EXIST, repositoryGroup.getId( )), 303 );
+ }
+ catch ( RepositoryAdminException 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 RepositoryGroup updateRepositoryGroup( String groupId, RepositoryGroup repositoryGroup ) throws ArchivaRestServiceException
+ {
+ org.apache.archiva.admin.model.beans.RepositoryGroup updateGroup = toModel( repositoryGroup );
+ try
+ {
+ org.apache.archiva.admin.model.beans.RepositoryGroup originGroup = repositoryGroupAdmin.getRepositoryGroup( groupId );
+ if ( StringUtils.isEmpty( updateGroup.getId())) {
+ updateGroup.setId( groupId );
+ }
+ if (StringUtils.isEmpty( updateGroup.getLocation() )) {
+ updateGroup.setLocation( originGroup.getLocation() );
+ }
+ if (StringUtils.isEmpty( updateGroup.getMergedIndexPath() )) {
+ updateGroup.setMergedIndexPath( originGroup.getMergedIndexPath() );
+ }
+ repositoryGroupAdmin.updateRepositoryGroup( updateGroup, getAuditInformation( ) );
+ return RepositoryGroup.of( repositoryGroupAdmin.getRepositoryGroup( groupId ) );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ log.error( "Repository admin error: {}", e.getMessage( ), e );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
+ }
+ }
+
+ @Override
+ public Response deleteRepositoryGroup( String repositoryGroupId ) throws ArchivaRestServiceException
+ {
+ return null;
+ }
+
+ @Override
+ public RepositoryGroup addRepositoryToGroup( String repositoryGroupId, String repositoryId ) throws ArchivaRestServiceException
+ {
+ return null;
+ }
+
+ @Override
+ public RepositoryGroup deleteRepositoryFromGroup( String repositoryGroupId, String repositoryId ) throws org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException
+ {
+ return null;
+ }
+}
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/ErrorKeys.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/ErrorKeys.java
index 83fec93..9f65161 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/ErrorKeys.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/v2/ErrorKeys.java
@@ -16,12 +16,19 @@ package org.apache.archiva.rest.services.v2;/*
* under the License.
*/
+import org.apache.archiva.rest.api.services.v2.ErrorMessage;
+
+import java.util.List;
+
/**
* @author Martin Stockhammer <ma...@apache.org>
*/
public interface ErrorKeys
{
+ String PREFIX = "archiva.";
+ String REPOSITORY_GROUP_PREFIX = PREFIX + "repository_group.";
+
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";
@@ -38,4 +45,8 @@ public interface ErrorKeys
String MISSING_DATA = "archiva.missing.data";
+ String REPOSITORY_GROUP_NOT_EXIST = REPOSITORY_GROUP_PREFIX+"notexist";
+ String REPOSITORY_GROUP_ADD_FAILED = REPOSITORY_GROUP_PREFIX+"add.failed" ;
+ String REPOSITORY_GROUP_EXIST = REPOSITORY_GROUP_PREFIX+"exists";
+
}