Search in sources :

Example 1 with CollisionException

use of org.eclipse.vorto.repository.services.exceptions.CollisionException in project vorto by eclipse.

the class NamespaceService method create.

// namespace operations
/**
 * This creates a new namespace with the given name, setting the given target {@link User} as
 * owner, and giving them all available roles on that namespace. <br/>
 * The difference between the actor and target users is that depending on the repository roles of
 * the actor user, some operations may not succeed.<br/>
 * For instance, if the actor and target are the same user (typical situation when a user
 * requests to create their own namespace), but the user is not a sysadmin and already has a
 * private namespace, the creation would fail (one private namespace per user). <br/>
 * However, if the actor was sysadmin and creating, e.g. an official namespace for a target user
 * who happens to already have a private namespace, the operation should succeed. <br/>
 * The operation can fail the given {@link User} or namespace name are invalid. <br/>
 * Examples of invalid {@link User} or namespace are:
 * <ul>
 *   <li>
 *     The user is {@code null}, has a {@code null} user name, or does not exist.
 *   </li>
 *   <li>
 *     The namespace name is {@code null}, empty, does not conform to naming standards (lowercase
 *     ASCII alphanumerics, dots as separators, underscores allowed).
 *   </li>
 *   <li>
 *     A namespace with that name already exists.
 *   </li>
 * </ul>
 * This method is invoked in two distinct cases:
 * <ol>
 *   <li>
 *     A user creates their own private namespace.
 *   </li>
 *   <li>
 *     A sysadmin creates an official namespace for any user, including themselves.
 *   </li>
 * </ol>
 * This method only deals with creating namespaces. <br/>
 *
 * @param actor
 * @param target
 * @param namespaceName
 * @return
 * @throws IllegalArgumentException
 * @throws DoesNotExistException
 * @throws CollisionException
 * @throws NameSyntaxException
 */
@Transactional(rollbackFor = { DoesNotExistException.class, CollisionException.class, NameSyntaxException.class, PrivateNamespaceQuotaExceededException.class, OperationForbiddenException.class })
public Namespace create(User actor, User target, String namespaceName) throws IllegalArgumentException, DoesNotExistException, CollisionException, NameSyntaxException, PrivateNamespaceQuotaExceededException, OperationForbiddenException {
    // boilerplate null validation
    ServiceValidationUtil.validate(actor, target);
    ServiceValidationUtil.validateNulls(namespaceName);
    // lightweight validation of required properties
    ServiceValidationUtil.validateNulls(actor.getId(), target.getId());
    if (namespaceName.trim().isEmpty()) {
        throw new NameSyntaxException(String.format("Namespace name is empty - aborting namespace creation.", namespaceName));
    }
    // pattern-based namespace name validation
    if (!VALID_NAMESPACE_NAME.matcher(namespaceName).matches()) {
        throw new NameSyntaxException(String.format("[%s] is not a valid namespace name - aborting namespace creation.", namespaceName));
    }
    // namespace collision validation
    if (cache.namespace(namespaceName).isPresent()) {
        throw new CollisionException(String.format("A namespace with name [%s] already exists - aborting namespace creation.", namespaceName));
    }
    // actor is not sysadmin - need to enforce quota validation and private namespace notation
    if (!userRepositoryRoleService.isSysadmin(actor)) {
        if (!namespaceName.startsWith(PRIVATE_NAMESPACE_PREFIX)) {
            throw new NameSyntaxException(String.format("[%s] is an invalid name for a private namespace - aborting namespace creation.", namespaceName));
        }
        verifyPrivateNamespaceQuota(actor, target);
    }
    // persists the new namespace
    Namespace namespace = new Namespace();
    namespace.setName(namespaceName);
    namespace.setWorkspaceId(UUID.randomUUID().toString().replace("-", ""));
    namespaceRepository.save(namespace);
    userNamespaceRoleService.setAllRoles(actor, target, namespace, true);
    // making cache stale so it will load the newly created namespace upon next usage within request
    cache.stale();
    // application event handling
    eventPublisher.publishEvent(new AppEvent(this, target.getUsername(), UserContext.user(target.getUsername(), namespace.getWorkspaceId()), EventType.NAMESPACE_ADDED));
    return namespace;
}
Also used : AppEvent(org.eclipse.vorto.repository.core.events.AppEvent) CollisionException(org.eclipse.vorto.repository.services.exceptions.CollisionException) NameSyntaxException(org.eclipse.vorto.repository.services.exceptions.NameSyntaxException) Namespace(org.eclipse.vorto.repository.domain.Namespace) Transactional(org.springframework.transaction.annotation.Transactional)

Example 2 with CollisionException

use of org.eclipse.vorto.repository.services.exceptions.CollisionException in project vorto by eclipse.

the class NamespaceController method createNamespace.

/**
 * Creates a new namespace with the given name for the authenticated user. <br/>
 * Automatically adds the user as owner and gives them all applicable roles on the namespace.<br/>
 * Subject to restrictions in terms of number of private namespaces owned, and whether the user
 * has the sufficient repository privileges to own a non-private namespace.
 *
 * @param namespace
 * @return
 */
@PutMapping(value = "/{namespace:.+}", produces = "application/json")
@PreAuthorize("isAuthenticated()")
public ResponseEntity<OperationResult> createNamespace(@ApiParam(value = "The name of the namespace to be created", required = true) @PathVariable final String namespace) {
    try {
        IUserContext userContext = UserContext.user(SecurityContextHolder.getContext().getAuthentication());
        namespaceService.create(userContext.getUsername(), userContext.getUsername(), namespace);
        return new ResponseEntity<>(OperationResult.success(), HttpStatus.CREATED);
    } catch (DoesNotExistException | NameSyntaxException e) {
        return new ResponseEntity<>(OperationResult.failure(e.getMessage()), HttpStatus.BAD_REQUEST);
    } catch (PrivateNamespaceQuotaExceededException pnqee) {
        return new ResponseEntity<>(OperationResult.failure(pnqee.getMessage()), HttpStatus.FORBIDDEN);
    }// omitting explicit collision message and just going with status here
     catch (CollisionException ce) {
        return new ResponseEntity<>(OperationResult.failure(""), HttpStatus.CONFLICT);
    } catch (OperationForbiddenException ofe) {
        return new ResponseEntity<>(OperationResult.failure(ofe.getMessage()), HttpStatus.FORBIDDEN);
    }
}
Also used : IUserContext(org.eclipse.vorto.repository.core.IUserContext) ResponseEntity(org.springframework.http.ResponseEntity) DoesNotExistException(org.eclipse.vorto.repository.services.exceptions.DoesNotExistException) OperationForbiddenException(org.eclipse.vorto.repository.services.exceptions.OperationForbiddenException) PrivateNamespaceQuotaExceededException(org.eclipse.vorto.repository.services.exceptions.PrivateNamespaceQuotaExceededException) CollisionException(org.eclipse.vorto.repository.services.exceptions.CollisionException) NameSyntaxException(org.eclipse.vorto.repository.services.exceptions.NameSyntaxException) PutMapping(org.springframework.web.bind.annotation.PutMapping) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Aggregations

CollisionException (org.eclipse.vorto.repository.services.exceptions.CollisionException)2 NameSyntaxException (org.eclipse.vorto.repository.services.exceptions.NameSyntaxException)2 IUserContext (org.eclipse.vorto.repository.core.IUserContext)1 AppEvent (org.eclipse.vorto.repository.core.events.AppEvent)1 Namespace (org.eclipse.vorto.repository.domain.Namespace)1 DoesNotExistException (org.eclipse.vorto.repository.services.exceptions.DoesNotExistException)1 OperationForbiddenException (org.eclipse.vorto.repository.services.exceptions.OperationForbiddenException)1 PrivateNamespaceQuotaExceededException (org.eclipse.vorto.repository.services.exceptions.PrivateNamespaceQuotaExceededException)1 ResponseEntity (org.springframework.http.ResponseEntity)1 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)1 Transactional (org.springframework.transaction.annotation.Transactional)1 PutMapping (org.springframework.web.bind.annotation.PutMapping)1