Refactor hawkbit core and security (#2833)
* Refactor hawkbit core and security * improve access to the base core features - static * thus easiear access * and less boilerplate passing of instances Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com> * Refactor context classes * make JSON context serialization default * AccessContext * Split hawkbit-security-core to other modules and remove it --------- Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -29,14 +29,12 @@
|
|||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<groupId>org.springframework.security</groupId>
|
||||||
<artifactId>hawkbit-repository-jpa</artifactId>
|
<artifactId>spring-security-web</artifactId>
|
||||||
<version>${project.version}</version>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
<artifactId>hawkbit-security-core</artifactId>
|
<artifactId>hawkbit-repository-jpa</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|||||||
@@ -9,30 +9,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.autoconfigure.security;
|
package org.eclipse.hawkbit.autoconfigure.security;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Optional;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ContextAware;
|
|
||||||
import org.eclipse.hawkbit.audit.AuditContextProvider;
|
|
||||||
import org.eclipse.hawkbit.audit.AuditLoggingAspect;
|
import org.eclipse.hawkbit.audit.AuditLoggingAspect;
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.repository.RepositoryConfiguration;
|
import org.eclipse.hawkbit.repository.RepositoryConfiguration;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware.DefaultTenantResolver;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware.TenantResolver;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAwareUserProperties;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAwareUserProperties.User;
|
|
||||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.InMemoryUserAuthoritiesResolver;
|
import org.eclipse.hawkbit.tenancy.TenantAwareUserProperties;
|
||||||
import org.eclipse.hawkbit.security.MdcHandler;
|
|
||||||
import org.eclipse.hawkbit.security.SecurityContextSerializer;
|
|
||||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
|
||||||
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
|
|
||||||
import org.eclipse.hawkbit.security.SpringSecurityAuditorAware;
|
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
|
||||||
import org.eclipse.hawkbit.tenancy.UserAuthoritiesResolver;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||||
@@ -41,14 +24,12 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.data.domain.AuditorAware;
|
import org.springframework.data.domain.AuditorAware;
|
||||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
|
||||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
|
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
|
||||||
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
|
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link EnableAutoConfiguration Auto-configuration} for security.
|
* {@link EnableAutoConfiguration Auto-configuration} for security.
|
||||||
@@ -58,48 +39,6 @@ import org.springframework.util.CollectionUtils;
|
|||||||
@Import(RepositoryConfiguration.class)
|
@Import(RepositoryConfiguration.class)
|
||||||
public class SecurityAutoConfiguration {
|
public class SecurityAutoConfiguration {
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a {@link ContextAware} (hence {@link TenantAware}) bean based on the given {@link UserAuthoritiesResolver},
|
|
||||||
* {@link SecurityContextSerializer} and {@link TenantResolver}.
|
|
||||||
*
|
|
||||||
* @param authoritiesResolver The user authorities/roles resolver
|
|
||||||
* @param securityContextSerializer The security context serializer (optional, if not found the default {@link SecurityContextSerializer#NOP} is used).
|
|
||||||
* @param tenantResolver The tenant resolver (optional, if not found the default {@link DefaultTenantResolver} is used).
|
|
||||||
* @return the {@link ContextAware} singleton bean.
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public ContextAware contextAware(
|
|
||||||
final UserAuthoritiesResolver authoritiesResolver,
|
|
||||||
@Autowired(required = false) final SecurityContextSerializer securityContextSerializer,
|
|
||||||
@Autowired(required = false) final TenantResolver tenantResolver) {
|
|
||||||
return new SecurityContextTenantAware(authoritiesResolver, securityContextSerializer, tenantResolver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a {@link UserAuthoritiesResolver} bean that is responsible for resolving user authorities/roles.
|
|
||||||
*
|
|
||||||
* @param securityProperties The Spring {@link SecurityProperties} for the security user
|
|
||||||
* @param tenantAwareUserProperties The {@link TenantAwareUserProperties} for the managed users
|
|
||||||
* @return an {@link InMemoryUserAuthoritiesResolver} bean
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public UserAuthoritiesResolver inMemoryAuthoritiesResolver(
|
|
||||||
final SecurityProperties securityProperties,
|
|
||||||
final TenantAwareUserProperties tenantAwareUserProperties) {
|
|
||||||
final Map<String, User> tenantAwareUsers = tenantAwareUserProperties.getUser();
|
|
||||||
final Map<String, List<String>> usersToPermissions;
|
|
||||||
if (!CollectionUtils.isEmpty(tenantAwareUsers)) {
|
|
||||||
usersToPermissions = tenantAwareUsers.entrySet().stream().collect(
|
|
||||||
Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getRoles()));
|
|
||||||
} else {
|
|
||||||
usersToPermissions = Collections.singletonMap(securityProperties.getUser().getName(),
|
|
||||||
securityProperties.getUser().getRoles());
|
|
||||||
}
|
|
||||||
return new InMemoryUserAuthoritiesResolver(usersToPermissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the auditor aware.
|
* Creates the auditor aware.
|
||||||
*
|
*
|
||||||
@@ -108,13 +47,7 @@ public class SecurityAutoConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public AuditorAware<String> auditorAware() {
|
public AuditorAware<String> auditorAware() {
|
||||||
return new SpringSecurityAuditorAware();
|
return () -> Optional.ofNullable(AccessContext.actor());
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public AuditContextProvider auditContextProvider() {
|
|
||||||
return AuditContextProvider.getInstance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -123,28 +56,6 @@ public class SecurityAutoConfiguration {
|
|||||||
return new AuditLoggingAspect();
|
return new AuditLoggingAspect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param tenantAware singleton bean
|
|
||||||
* @return tenantAware {@link SystemSecurityContext}
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public SystemSecurityContext systemSecurityContext(final TenantAware tenantAware, final RoleHierarchy roleHierarchy) {
|
|
||||||
return new SystemSecurityContext(tenantAware, roleHierarchy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public MdcHandler mdcHandler() {
|
|
||||||
return MdcHandler.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public SecurityTokenGenerator securityTokenGenerator() {
|
|
||||||
return new SecurityTokenGenerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public AuthenticationSuccessHandler authenticationSuccessHandler() {
|
public AuthenticationSuccessHandler authenticationSuccessHandler() {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.autoconfigure.security;
|
package org.eclipse.hawkbit.autoconfigure.security;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.im.authentication.StaticAuthenticationProvider;
|
import org.eclipse.hawkbit.auth.StaticAuthenticationProvider;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAwareUserProperties;
|
import org.eclipse.hawkbit.tenancy.TenantAwareUserProperties;
|
||||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ hawkbit.artifact.url.protocols.download-http.hostname=localhost
|
|||||||
hawkbit.artifact.url.protocols.download-http.ip=127.0.0.1
|
hawkbit.artifact.url.protocols.download-http.ip=127.0.0.1
|
||||||
hawkbit.artifact.url.protocols.download-http.protocol=http
|
hawkbit.artifact.url.protocols.download-http.protocol=http
|
||||||
hawkbit.artifact.url.protocols.download-http.port=8080
|
hawkbit.artifact.url.protocols.download-http.port=8080
|
||||||
hawkbit.artifact.url.protocols.download-http.supports=DMF,DDI
|
hawkbit.artifact.url.protocols.download-http.supports=DDI,DMF
|
||||||
hawkbit.artifact.url.protocols.download-http.ref={protocolRequest}://{hostnameRequest}:{portRequest}/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}
|
hawkbit.artifact.url.protocols.download-http.ref={protocolRequest}://{hostnameRequest}:{portRequest}/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}
|
||||||
hawkbit.artifact.url.protocols.md5sum-http.rel=md5sum-http
|
hawkbit.artifact.url.protocols.md5sum-http.rel=md5sum-http
|
||||||
hawkbit.artifact.url.protocols.md5sum-http.protocol=${hawkbit.artifact.url.protocols.download-http.protocol}
|
hawkbit.artifact.url.protocols.md5sum-http.protocol=${hawkbit.artifact.url.protocols.download-http.protocol}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
|
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
@@ -47,6 +46,20 @@
|
|||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-context-support</artifactId>
|
<artifactId>spring-context-support</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-oauth2-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-aspects</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-web</artifactId>
|
||||||
|
<!-- needed for web MDC filter -->
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.validation</groupId>
|
<groupId>jakarta.validation</groupId>
|
||||||
@@ -65,6 +78,13 @@
|
|||||||
<artifactId>caffeine</artifactId>
|
<artifactId>caffeine</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<!-- needed for JSON context serialization -->
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- TEST -->
|
<!-- TEST -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.github.classgraph</groupId>
|
<groupId>io.github.classgraph</groupId>
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2023 Bosch.IO GmbH and others
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made
|
|
||||||
* available under the terms of the Eclipse Public License 2.0
|
|
||||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
|
||||||
*/
|
|
||||||
package org.eclipse.hawkbit;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link ContextAware} provides means for getting the current context (via {@link #getCurrentContext()}) and then
|
|
||||||
* to execute a {@link Runnable} or a {@link Function} in the same context using {@link #runInContext(String, Runnable)}
|
|
||||||
* or {@link #runInContext(String, Function, Object)}.
|
|
||||||
* <p/>
|
|
||||||
* This is useful for scheduled background operations like rollouts and auto assignments where they shall
|
|
||||||
* be processed in the scope of the creator.
|
|
||||||
*/
|
|
||||||
public interface ContextAware extends TenantAware {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the current context encoded as a {@link String}. Depending on the implementation it could,
|
|
||||||
* for instance, be a serialized context or a reference to such.
|
|
||||||
*
|
|
||||||
* @return could be empty if there is nothing to serialize or context aware is not supported.
|
|
||||||
*/
|
|
||||||
Optional<String> getCurrentContext();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap a specific execution in a known and pre-serialized context.
|
|
||||||
*
|
|
||||||
* @param <T> the type of the input to the function
|
|
||||||
* @param <R> the type of the result of the function
|
|
||||||
* @param serializedContext created by {@link #getCurrentContext()}. Must be non-<code>null</code>.
|
|
||||||
* @param function function to call in the reconstructed context. Must be non-<code>null</code>.
|
|
||||||
* @param t the argument that will be passed to the function
|
|
||||||
* @return the function result
|
|
||||||
*/
|
|
||||||
<T, R> R runInContext(String serializedContext, Function<T, R> function, T t);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap a specific execution in a known and pre-serialized context.
|
|
||||||
*
|
|
||||||
* @param serializedContext created by {@link #getCurrentContext()}. Must be non-<code>null</code>.
|
|
||||||
* @param runnable runnable to call in the reconstructed context. Must be non-<code>null</code>.
|
|
||||||
*/
|
|
||||||
default void runInContext(String serializedContext, Runnable runnable) {
|
|
||||||
Objects.requireNonNull(runnable);
|
|
||||||
runInContext(serializedContext, v -> {
|
|
||||||
runnable.run();
|
|
||||||
return null;
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Contributors to the Eclipse Foundation
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.audit;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
|
|
||||||
|
@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE)
|
||||||
|
@SuppressWarnings("java:S6548") // java:S6548 - singleton holder ensures static access to spring resources in some places
|
||||||
|
public class AuditContextProvider {
|
||||||
|
|
||||||
|
public static AuditContext getAuditContext() {
|
||||||
|
return new AuditContext(
|
||||||
|
Optional.ofNullable(AccessContext.tenant()).orElse("n/a"),
|
||||||
|
Optional.ofNullable(AccessContext.actor()).orElse(AccessContext.SYSTEM_ACTOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
public record AuditContext(String tenant, String username) {}
|
||||||
|
}
|
||||||
@@ -17,8 +17,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public class AuditLogger {
|
public class AuditLogger {
|
||||||
|
|
||||||
private static final AuditContextProvider AUDIT_CONTEXT_PROVIDER = AuditContextProvider.getInstance();
|
|
||||||
|
|
||||||
public static void info(final String entity, final String message) {
|
public static void info(final String entity, final String message) {
|
||||||
logMessage(entity, message, AuditLog.Level.INFO);
|
logMessage(entity, message, AuditLog.Level.INFO);
|
||||||
}
|
}
|
||||||
@@ -44,13 +42,13 @@ public class AuditLogger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void logMessage(final String entity, final String message, final AuditLog.Level level) {
|
private static void logMessage(final String entity, final String message, final AuditLog.Level level) {
|
||||||
logMessage(AUDIT_CONTEXT_PROVIDER.getAuditContext().tenant(), AUDIT_CONTEXT_PROVIDER.getAuditContext().username(), entity, message,
|
final AuditContextProvider.AuditContext auditContext = AuditContextProvider.getAuditContext();
|
||||||
level);
|
logMessage(auditContext.tenant(), auditContext.username(), entity, message, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void logMessage(
|
private static void logMessage(
|
||||||
final String tenant, final String username, final String entity, final String message, final AuditLog.Level level) {
|
final String tenant, final String username, final String entity, final String message, final AuditLog.Level level) {
|
||||||
final String logMessage = String.format("[%s] User: %s, Tenant: %s - %s", entity, username, tenant, message);
|
final String logMessage = String.format("[%s] User: %s, AccessContext: %s - %s", entity, username, tenant, message);
|
||||||
final Logger auditLogger = LoggerFactory.getLogger("AUDIT" + (entity != null ? ("." + entity.toUpperCase()) : ""));
|
final Logger auditLogger = LoggerFactory.getLogger("AUDIT" + (entity != null ? ("." + entity.toUpperCase()) : ""));
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case INFO:
|
case INFO:
|
||||||
@@ -70,8 +70,8 @@ public class AuditLoggingAspect {
|
|||||||
* Logs both the request details and the response.
|
* Logs both the request details and the response.
|
||||||
*/
|
*/
|
||||||
private void logAudit(
|
private void logAudit(
|
||||||
final JoinPoint joinPoint, final AuditLog auditLog, final String resultMessage, final String paramsToLog,
|
final JoinPoint joinPoint,
|
||||||
final AuditLog.Level logLevel) {
|
final AuditLog auditLog, final String resultMessage, final String paramsToLog, final AuditLog.Level logLevel) {
|
||||||
final String methodName = joinPoint.getSignature().getName();
|
final String methodName = joinPoint.getSignature().getName();
|
||||||
|
|
||||||
final String logMessage = String.format(
|
final String logMessage = String.format(
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
* Copyright (c) 2025 Contributors to the Eclipse Foundation
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials are made
|
* This program and the accompanying materials are made
|
||||||
* available under the terms of the Eclipse Public License 2.0
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
@@ -7,19 +7,18 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.audit;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants related to security.
|
* Constants related to security.
|
||||||
*/
|
*/
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public final class SecurityConstants {
|
public final class SecurityLogger {
|
||||||
|
|
||||||
/**
|
public static final Logger LOGGER = LoggerFactory.getLogger("SERVER.SECURITY");
|
||||||
* Logger prefix used for security logging.
|
|
||||||
*/
|
|
||||||
public static final String SECURITY_LOG_PREFIX = "server-security";
|
|
||||||
}
|
}
|
||||||
@@ -7,10 +7,11 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.im.authentication;
|
package org.eclipse.hawkbit.auth;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||||
|
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public class Hierarchy {
|
public class Hierarchy {
|
||||||
@@ -23,4 +24,14 @@ public class Hierarchy {
|
|||||||
SpPermission.TENANT_CONFIGURATION_HIERARCHY +
|
SpPermission.TENANT_CONFIGURATION_HIERARCHY +
|
||||||
SpRole.DEFAULT_ROLE_HIERARCHY;
|
SpRole.DEFAULT_ROLE_HIERARCHY;
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
|
private static RoleHierarchy roleHierarchy;
|
||||||
|
|
||||||
|
public static RoleHierarchy getRoleHierarchy() {
|
||||||
|
return roleHierarchy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setRoleHierarchy(final RoleHierarchy roleHierarchy) {
|
||||||
|
Hierarchy.roleHierarchy = roleHierarchy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,8 +7,9 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.im.authentication;
|
package org.eclipse.hawkbit.auth;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -16,7 +17,12 @@ import java.util.Set;
|
|||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.function.SingletonSupplier;
|
import org.springframework.util.function.SingletonSupplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -164,4 +170,27 @@ public final class SpPermission {
|
|||||||
public static Set<String> getAllTenantAuthorities() {
|
public static Set<String> getAllTenantAuthorities() {
|
||||||
return ALL_TENANT_AUTHORITIES.get();
|
return ALL_TENANT_AUTHORITIES.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("java:S3776") // java:S3776 - better in one place for better readability
|
||||||
|
public static boolean hasPermission(final String permission) {
|
||||||
|
final SecurityContext context = SecurityContextHolder.getContext();
|
||||||
|
if (context != null) {
|
||||||
|
final Authentication authentication = context.getAuthentication();
|
||||||
|
if (authentication != null) {
|
||||||
|
Collection<? extends GrantedAuthority> grantedAuthorities = authentication.getAuthorities();
|
||||||
|
final RoleHierarchy roleHierarchy = Hierarchy.getRoleHierarchy();
|
||||||
|
if (!ObjectUtils.isEmpty(grantedAuthorities)) {
|
||||||
|
if (roleHierarchy != null) {
|
||||||
|
grantedAuthorities = roleHierarchy.getReachableGrantedAuthorities(grantedAuthorities);
|
||||||
|
}
|
||||||
|
for (final GrantedAuthority authority : grantedAuthorities) {
|
||||||
|
if (authority.getAuthority().equals(permission)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.im.authentication;
|
package org.eclipse.hawkbit.auth;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.im.authentication;
|
package org.eclipse.hawkbit.auth;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@@ -23,7 +23,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
|||||||
* hasRole([role]) Returns true if the current principal has the specified role.
|
* hasRole([role]) Returns true if the current principal has the specified role.
|
||||||
* hasAnyRole([role1,role2]) Returns true if the current principal has any of the supplied roles (given as a comma-separated list of strings)
|
* hasAnyRole([role1,role2]) Returns true if the current principal has any of the supplied roles (given as a comma-separated list of strings)
|
||||||
* principal Allows direct access to the principal object representing the current user
|
* principal Allows direct access to the principal object representing the current user
|
||||||
* authentication Allows direct access to the current Authentication object obtained from the SecurityContext
|
* auth Allows direct access to the current Authentication object obtained from the SecurityContext
|
||||||
* permitAll Always evaluates to true
|
* permitAll Always evaluates to true
|
||||||
* denyAll Always evaluates to false
|
* denyAll Always evaluates to false
|
||||||
* isAnonymous() Returns true if the current principal is an anonymous user
|
* isAnonymous() Returns true if the current principal is an anonymous user
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.im.authentication;
|
package org.eclipse.hawkbit.auth;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -82,8 +82,10 @@ public class StaticAuthenticationProvider extends DaoAuthenticationProvider {
|
|||||||
return new FixedInMemoryTenantAwareUserDetailsService(userPrincipals);
|
return new FixedInMemoryTenantAwareUserDetailsService(userPrincipals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Pattern HAS_SCHEMA = Pattern.compile("^\\{[^{]+}.+$");
|
||||||
|
|
||||||
private static String password(final String password) {
|
private static String password(final String password) {
|
||||||
return !Pattern.compile("^\\{.+}.*$").matcher(password).matches() ? "{noop}" + password : password;
|
return !HAS_SCHEMA.matcher(password).matches() ? "{noop}" + password : password;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<GrantedAuthority> createAuthorities(
|
private static List<GrantedAuthority> createAuthorities(
|
||||||
@@ -0,0 +1,449 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.context;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.eclipse.hawkbit.auth.SpRole;
|
||||||
|
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
||||||
|
import org.eclipse.hawkbit.tenancy.TenantAwareUser;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 'static' class providing methods related to access context:
|
||||||
|
* <ul>
|
||||||
|
* <li>read / lookup - find out the current tenant, principal (actor), security context</li>
|
||||||
|
* <li>switch context - run code as system, as system but scoped for a tenant, with a specific context</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
@Slf4j
|
||||||
|
public class AccessContext {
|
||||||
|
|
||||||
|
// Note! There shall be no regular 'system'!
|
||||||
|
public static final String SYSTEM_ACTOR = "system";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current context encoded as a {@link String}. Depending on the implementation it could,
|
||||||
|
* for instance, be a serialized context or a reference to such.
|
||||||
|
*
|
||||||
|
* @return could be empty if there is nothing to serialize or context aware is not supported.
|
||||||
|
*/
|
||||||
|
public static Optional<String> securityContext() {
|
||||||
|
return Optional.ofNullable(SecurityContextHolder.getContext()).map(AccessContext::serialize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation might retrieve the current tenant from a session or thread-local.
|
||||||
|
*
|
||||||
|
* @return the current tenant
|
||||||
|
*/
|
||||||
|
public static String tenant() {
|
||||||
|
final SecurityContext context = SecurityContextHolder.getContext();
|
||||||
|
if (context.getAuthentication() != null) {
|
||||||
|
final Object principal = context.getAuthentication().getPrincipal();
|
||||||
|
if (context.getAuthentication().getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareAuthenticationDetails) {
|
||||||
|
return tenantAwareAuthenticationDetails.tenant();
|
||||||
|
} else if (principal instanceof TenantAwareUser tenantAwareUser) {
|
||||||
|
return tenantAwareUser.getTenant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sometimes 'system' need to override the auditor when do create/modify actions in context of a tenant and user.
|
||||||
|
// Though this could be made using runAsTenantAsUser sometimes (as in transaction) this override is needed
|
||||||
|
// after runAsTenantAsUser (because it seems that auditor is got in commit time).
|
||||||
|
// So this thread local variable provides option to override explicitly the auditor.
|
||||||
|
private static final ThreadLocal<String> ACTOR_OVERRIDE = new ThreadLocal<>();
|
||||||
|
|
||||||
|
// Return the current actor / auditor / principal name. It could be a user (person), technical user, device, etc.
|
||||||
|
public static String actor() {
|
||||||
|
if (ACTOR_OVERRIDE.get() != null) {
|
||||||
|
return ACTOR_OVERRIDE.get();
|
||||||
|
} else {
|
||||||
|
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
if (isAuthenticationInvalid(authentication)) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return resolve(authentication);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap a specific execution in a known and pre-serialized context.
|
||||||
|
*
|
||||||
|
* @param serializedContext created by {@link #securityContext()}. Must be non-<code>null</code>.
|
||||||
|
* @param runnable runnable to run in the reconstructed context. Must be non-<code>null</code>.
|
||||||
|
*/
|
||||||
|
public static void withSecurityContext(final String serializedContext, final Runnable runnable) {
|
||||||
|
Objects.requireNonNull(runnable);
|
||||||
|
withSecurityContext(serializedContext, () -> {
|
||||||
|
runnable.run();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap a specific execution / call in a known and pre-serialized context.
|
||||||
|
*
|
||||||
|
* @param <T> the type of the output of the supplier
|
||||||
|
* @param serializedContext created by {@link #securityContext()}. Must be non-<code>null</code>.
|
||||||
|
* @param supplier function to call in the reconstructed context. Must be non-<code>null</code>.
|
||||||
|
* @return the function result
|
||||||
|
*/
|
||||||
|
public static <T> T withSecurityContext(final String serializedContext, final Supplier<T> supplier) {
|
||||||
|
Objects.requireNonNull(serializedContext);
|
||||||
|
Objects.requireNonNull(supplier);
|
||||||
|
final SecurityContext securityContext = deserialize(serializedContext);
|
||||||
|
Objects.requireNonNull(securityContext);
|
||||||
|
|
||||||
|
return withSecurityContext(securityContext, supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T withSecurityContext(final SecurityContext securityContext, final Supplier<T> supplier) {
|
||||||
|
final SecurityContext originalContext = SecurityContextHolder.getContext();
|
||||||
|
if (Objects.equals(securityContext, originalContext)) {
|
||||||
|
return supplier.get();
|
||||||
|
} else {
|
||||||
|
SecurityContextHolder.setContext(securityContext);
|
||||||
|
try {
|
||||||
|
return Mdc.withAuthRe(supplier::get);
|
||||||
|
} finally {
|
||||||
|
SecurityContextHolder.setContext(originalContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void asActor(final String actor, final Runnable runnable) {
|
||||||
|
asActor(actor, () -> {
|
||||||
|
runnable.run();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T asActor(final String actor, final Supplier<T> supplier) {
|
||||||
|
final String currentAuditor = ACTOR_OVERRIDE.get();
|
||||||
|
try {
|
||||||
|
setActor(actor);
|
||||||
|
return supplier.get();
|
||||||
|
} finally {
|
||||||
|
setActor(currentAuditor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a given {@link Runnable} within a system security context, which is permitted to call secured system code. Often the system needs
|
||||||
|
* to call secured methods by its own without relying on the current security context e.g. if the current security context does not contain
|
||||||
|
* the necessary permission it's necessary to execute code as system code to execute necessary methods and functionality. <br/>
|
||||||
|
* The security context will be switched to the system code and back after the supplier is called. <br/>
|
||||||
|
* The system code is executed for a current tenant by using the {@link AccessContext#tenant()}.
|
||||||
|
*
|
||||||
|
* @param runnable the runnable to run within the system security context
|
||||||
|
*/
|
||||||
|
public static void asSystem(final Runnable runnable) {
|
||||||
|
asSystemAsTenant(tenant(), () -> {
|
||||||
|
runnable.run();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a given {@link Supplier} within a system security context, which is permitted to call secured system code. Often the system needs
|
||||||
|
* to call secured methods by its own without relying on the current security context e.g. if the current security context does not contain
|
||||||
|
* the necessary permission it's necessary to execute code as system code to execute necessary methods and functionality. <br/>
|
||||||
|
* The security context will be switched to the system code and back after the supplier is called. <br/>
|
||||||
|
* The system code is executed for a current tenant by using the {@link AccessContext#tenant()}.
|
||||||
|
*
|
||||||
|
* @param supplier the supplier to call within the system security context
|
||||||
|
* @return the return value of the {@link Supplier#get()} method.
|
||||||
|
*/
|
||||||
|
public static <T> T asSystem(final Supplier<T> supplier) {
|
||||||
|
return asSystemAsTenant(tenant(), supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a given {@link Runnable} within a system security context, which is permitted to call secured system code. Often the system needs
|
||||||
|
* to call secured methods by its own without relying on the current security context e.g. if the current security context does not contain
|
||||||
|
* the necessary permission it's necessary to execute code as system code to execute necessary methods and functionality.<br/>
|
||||||
|
* The security context will be switched to the system code and back after the runnable is run.<br/>
|
||||||
|
* The system code is executed for a specific given tenant by using the {@link AccessContext}.
|
||||||
|
*
|
||||||
|
* @param tenant the tenant to act as system code
|
||||||
|
* @param runnable the runnable to run within the system security context
|
||||||
|
*/
|
||||||
|
public static void asSystemAsTenant(final String tenant, final Runnable runnable) {
|
||||||
|
asSystemAsTenant(tenant, () -> {
|
||||||
|
runnable.run();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a given {@link Supplier} within a system security context, which is permitted to call secured system code. Often the system needs
|
||||||
|
* to call secured methods by its own without relying on the current security context e.g. if the current security context does not contain
|
||||||
|
* the necessary permission it's necessary to execute code as system code to execute necessary methods and functionality.<br/>
|
||||||
|
* The security context will be switched to the system code and back after the supplier is run.<br/>
|
||||||
|
* The system code is executed for a specific given tenant by using the {@link AccessContext}.
|
||||||
|
*
|
||||||
|
* @param tenant the tenant to act as system code
|
||||||
|
* @param supplier the supplier to call within the system security context
|
||||||
|
* @return the return value of the {@link Supplier#get()} method.
|
||||||
|
*/
|
||||||
|
public static <T> T asSystemAsTenant(final String tenant, final Supplier<T> supplier) {
|
||||||
|
final SecurityContext currentContext = SecurityContextHolder.getContext();
|
||||||
|
try {
|
||||||
|
log.debug("Entering system code execution");
|
||||||
|
final SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
|
||||||
|
securityContext.setAuthentication(new SystemCodeAuthentication(tenant));
|
||||||
|
return withSecurityContext(securityContext, supplier);
|
||||||
|
} finally {
|
||||||
|
SecurityContextHolder.setContext(currentContext);
|
||||||
|
log.debug("Leaving system code execution");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setActor(final String currentAuditor) {
|
||||||
|
if (currentAuditor == null) {
|
||||||
|
ACTOR_OVERRIDE.remove();
|
||||||
|
} else {
|
||||||
|
ACTOR_OVERRIDE.set(currentAuditor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if the current running code is running as system code block.
|
||||||
|
*/
|
||||||
|
public static boolean isCurrentThreadSystemCode() {
|
||||||
|
return SecurityContextHolder.getContext().getAuthentication() instanceof SystemCodeAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String resolve(final Authentication authentication) {
|
||||||
|
if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails && tenantAwareDetails.controller()) {
|
||||||
|
return "CONTROLLER_PLUG_AND_PLAY";
|
||||||
|
}
|
||||||
|
final Object principal = authentication.getPrincipal();
|
||||||
|
if (principal instanceof ActorAware actorAware) {
|
||||||
|
return actorAware.getActor();
|
||||||
|
}
|
||||||
|
if (principal instanceof UserDetails userDetails) {
|
||||||
|
return userDetails.getUsername();
|
||||||
|
}
|
||||||
|
if (principal instanceof OidcUser oidcUser) {
|
||||||
|
return oidcUser.getPreferredUsername();
|
||||||
|
}
|
||||||
|
return principal.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return security context as string (could be just a reference)
|
||||||
|
*
|
||||||
|
* @param securityContext the security context
|
||||||
|
* @return the securityContext as string
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("java:S112") // java:S112 - generic method
|
||||||
|
private static String serialize(final SecurityContext securityContext) {
|
||||||
|
Objects.requireNonNull(securityContext);
|
||||||
|
try {
|
||||||
|
return OBJECT_MAPPER.writeValueAsString(new SecCtxInfo(securityContext));
|
||||||
|
} catch (final JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize security context
|
||||||
|
*
|
||||||
|
* @param securityContextString string representing the security context
|
||||||
|
* @return deserialized security context
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("java:S112") // java:S112 - generic method
|
||||||
|
private static SecurityContext deserialize(final String securityContextString) {
|
||||||
|
Objects.requireNonNull(securityContextString);
|
||||||
|
final String securityContextTrimmed = securityContextString.trim();
|
||||||
|
try {
|
||||||
|
return OBJECT_MAPPER.readerFor(SecCtxInfo.class).<SecCtxInfo> readValue(securityContextTrimmed).toSecurityContext();
|
||||||
|
} catch (final JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isAuthenticationInvalid(final Authentication authentication) {
|
||||||
|
return authentication == null || !authentication.isAuthenticated() || authentication.getPrincipal() == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ActorAware {
|
||||||
|
|
||||||
|
String getActor();
|
||||||
|
}
|
||||||
|
|
||||||
|
// simplified info for the security context keeping just the basic info needed for background execution of
|
||||||
|
// controller auth is not supported - always is false
|
||||||
|
// only authenticated user is supported
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
private static class SecCtxInfo implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String tenant;
|
||||||
|
// auditor / username (auth principal name)
|
||||||
|
private String auditor = "n/a"; // default value "n/a" is used only on deserialization if field is missing
|
||||||
|
@JsonProperty(required = true)
|
||||||
|
private String[] authorities;
|
||||||
|
|
||||||
|
private SecCtxInfo(final SecurityContext securityContext) {
|
||||||
|
final Authentication authentication = securityContext.getAuthentication();
|
||||||
|
if (!authentication.isAuthenticated()) {
|
||||||
|
throw new IllegalStateException("Only authenticated context could be serialized");
|
||||||
|
}
|
||||||
|
if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails) {
|
||||||
|
if (tenantAwareDetails.controller()) {
|
||||||
|
throw new IllegalStateException("Controller auth context is not supported");
|
||||||
|
}
|
||||||
|
tenant = tenantAwareDetails.tenant();
|
||||||
|
} else if (authentication.getPrincipal() instanceof TenantAwareUser tenantAwareUser) {
|
||||||
|
tenant = tenantAwareUser.getTenant();
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep the auditor, ofr audit purposes,
|
||||||
|
// sets principal to the resolved auditor and then deserialized auth will return it as principal
|
||||||
|
// since the class is not known to auditor aware - it shall used default - principal as auditor
|
||||||
|
auditor = resolve(authentication);
|
||||||
|
authorities = authentication.getAuthorities().stream().map(Object::toString).toArray(String[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SecurityContext toSecurityContext() {
|
||||||
|
final SecurityContext ctx = SecurityContextHolder.createEmptyContext();
|
||||||
|
final Object details = tenant == null ? null : new TenantAwareAuthenticationDetails(tenant, false);
|
||||||
|
final ActorAware principal = () -> auditor;
|
||||||
|
final Collection<? extends GrantedAuthority> grantedAuthorities =
|
||||||
|
Stream.of(authorities).map(SimpleGrantedAuthority::new).toList();
|
||||||
|
ctx.setAuthentication(new Authentication() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getPrincipal() {
|
||||||
|
return principal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
|
return grantedAuthorities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAuthenticated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getDetails() {
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getCredentials() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return auditor;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of the Spring's {@link Authentication} object which is used within a system security code block and
|
||||||
|
* wraps the original auth object. The wrapped object contains the necessary {@link SpRole#SYSTEM_ROLE}
|
||||||
|
* which is allowed to execute all secured methods.
|
||||||
|
*/
|
||||||
|
static final class SystemCodeAuthentication implements Authentication {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final List<SimpleGrantedAuthority> AUTHORITIES = List.of(new SimpleGrantedAuthority(SpRole.SYSTEM_ROLE));
|
||||||
|
|
||||||
|
private final TenantAwareAuthenticationDetails details;
|
||||||
|
private final TenantAwareUser principal;
|
||||||
|
|
||||||
|
private SystemCodeAuthentication(final String tenant) {
|
||||||
|
details = new TenantAwareAuthenticationDetails(tenant, false);
|
||||||
|
principal = new TenantAwareUser(SYSTEM_ACTOR, SYSTEM_ACTOR, AUTHORITIES, tenant);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
|
return AUTHORITIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getCredentials() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getDetails() {
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getPrincipal() {
|
||||||
|
return principal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAuthenticated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAuthenticated(final boolean isAuthenticated) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,10 +7,11 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.context;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
@@ -22,8 +23,6 @@ import lombok.AccessLevel;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
||||||
import org.slf4j.MDC;
|
import org.slf4j.MDC;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
@@ -31,42 +30,34 @@ import org.springframework.security.web.access.intercept.AuthorizationFilter;
|
|||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
// java:S6548 - singleton holder ensures static access to spring resources in some places
|
|
||||||
// java:S112 - it is generic class so a generic exception is fine
|
// java:S112 - it is generic class so a generic exception is fine
|
||||||
@SuppressWarnings({ "java:S6548", "java:S112" })
|
@SuppressWarnings("java:S112")
|
||||||
public class MdcHandler {
|
public class Mdc {
|
||||||
|
|
||||||
public static final String MDC_KEY_TENANT = "tenant";
|
public static final String MDC_KEY_TENANT = "tenant";
|
||||||
public static final String MDC_KEY_USER = "user";
|
// in the MDC the default actor key is "user"
|
||||||
|
public static final String MDC_KEY_ACTOR = System.getProperty(
|
||||||
|
"hawkbit.mdc.actor.key", // first by priority: system property
|
||||||
|
Optional.ofNullable(System.getenv("HAWKBIT_MDC_ACTOR_KEY")) // second by priority: environment variable
|
||||||
|
.orElse("user")); // default if not set
|
||||||
|
|
||||||
private static final MdcHandler SINGLETON = new MdcHandler();
|
private static boolean enabled = true;
|
||||||
|
|
||||||
@Value("${hawkbit.logging.mdchandler.enabled:true}")
|
// hook to disable (otherwise enabled by default) MDC context management
|
||||||
private boolean mdcEnabled;
|
public static void setEnabled(final boolean enabled) {
|
||||||
private SpringSecurityAuditorAware springSecurityAuditorAware = new SpringSecurityAuditorAware();
|
Mdc.enabled = enabled;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The holder singleton instance.
|
|
||||||
*/
|
|
||||||
public static MdcHandler getInstance() {
|
|
||||||
return SINGLETON;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Autowired(required = false) // spring setter injection
|
|
||||||
public void setSpringSecurityAuditorAware(final SpringSecurityAuditorAware springSecurityAuditorAware) {
|
|
||||||
this.springSecurityAuditorAware = springSecurityAuditorAware;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or user from the authentication in the MDC context.
|
* Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or actor from the auth in the MDC context.
|
||||||
*
|
*
|
||||||
* @param <T> the return type
|
* @param <T> the return type
|
||||||
* @param callable the callable to execute
|
* @param callable the callable to execute
|
||||||
* @return the result
|
* @return the result
|
||||||
* @throws Exception if thrown by the callable
|
* @throws Exception if thrown by the callable
|
||||||
*/
|
*/
|
||||||
public <T> T callWithAuth(final Callable<T> callable) throws Exception {
|
public static <T> T withAuth(final Callable<T> callable) throws Exception {
|
||||||
if (!mdcEnabled) {
|
if (!enabled) {
|
||||||
return callable.call();
|
return callable.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,25 +73,24 @@ public class MdcHandler {
|
|||||||
tenant = null;
|
tenant = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String user = springSecurityAuditorAware
|
final String actor = Optional.ofNullable(AccessContext.actor())
|
||||||
.getCurrentAuditor()
|
.filter(ctxActor -> !ctxActor.equals(AccessContext.SYSTEM_ACTOR)) // null and system are the same - system actor
|
||||||
.filter(username -> !username.equals(SecurityContextTenantAware.SYSTEM_USER)) // null and system are the same - system user
|
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
return callWithTenantAndUser0(callable, tenant, user);
|
return asTenantAsActor0(tenant, actor, callable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or user from the authentication in the MDC context.
|
* Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or actor from the auth in the MDC context.
|
||||||
* Calls the {@link #callWithAuth(Callable)} method and wraps any catchable exception into a {@link RuntimeException}.
|
* Calls the {@link #withAuth(Callable)} method and wraps any catchable exception into a {@link RuntimeException}.
|
||||||
*
|
*
|
||||||
* @param <T> the return type
|
* @param <T> the return type
|
||||||
* @param callable the callable to execute
|
* @param callable the callable to execute
|
||||||
* @return the result
|
* @return the result
|
||||||
*/
|
*/
|
||||||
public <T> T callWithAuthRE(final Callable<T> callable) {
|
public static <T> T withAuthRe(final Callable<T> callable) {
|
||||||
try {
|
try {
|
||||||
return callWithAuth(callable);
|
return withAuth(callable);
|
||||||
} catch (final RuntimeException re) {
|
} catch (final RuntimeException re) {
|
||||||
throw re;
|
throw re;
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
@@ -109,35 +99,35 @@ public class MdcHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or user in the MDC context.
|
* Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or actor in the MDC context.
|
||||||
*
|
*
|
||||||
* @param <T> the return type
|
* @param <T> the return type
|
||||||
* @param callable the callable to execute
|
|
||||||
* @param tenant the tenant to set in the MDC context
|
* @param tenant the tenant to set in the MDC context
|
||||||
* @param user the user to set in the MDC context
|
* @param actor the actor to set in the MDC context
|
||||||
|
* @param callable the callable to execute
|
||||||
* @return the result
|
* @return the result
|
||||||
*/
|
*/
|
||||||
public <T> T callWithTenantAndUser(final Callable<T> callable, final String tenant, final String user) throws Exception {
|
public static <T> T asTenantAsActor(final String tenant, final String actor, final Callable<T> callable) throws Exception {
|
||||||
if (!mdcEnabled) {
|
if (!enabled) {
|
||||||
return callable.call();
|
return callable.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
return callWithTenantAndUser0(callable, tenant, user);
|
return asTenantAsActor0(tenant, actor, callable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or user from the authentication in the MDC context.
|
* Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or actor from the auth in the MDC context.
|
||||||
* Calls the {@link #callWithTenantAndUser(Callable, String, String)} method and wraps any catchable exception into a {@link RuntimeException}.
|
* Calls the {@link #asTenantAsActor(String, String, Callable)} method and wraps any catchable exception into a {@link RuntimeException}.
|
||||||
*
|
*
|
||||||
* @param <T> the return type
|
* @param <T> the return type
|
||||||
* @param callable the callable to execute
|
|
||||||
* @param tenant the tenant to set in the MDC context
|
* @param tenant the tenant to set in the MDC context
|
||||||
* @param user the user to set in the MDC context
|
* @param actor the actor to set in the MDC context
|
||||||
|
* @param callable the callable to execute
|
||||||
* @return the result
|
* @return the result
|
||||||
*/
|
*/
|
||||||
public <T> T callWithTenantAndUserRE(final Callable<T> callable, final String tenant, final String user) {
|
public static <T> T asTenantAsActorRe(final String tenant, final String actor, final Callable<T> callable) {
|
||||||
try {
|
try {
|
||||||
return callWithTenantAndUser(callable, tenant, user);
|
return asTenantAsActor(tenant, actor, callable);
|
||||||
} catch (final RuntimeException re) {
|
} catch (final RuntimeException re) {
|
||||||
throw re;
|
throw re;
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
@@ -145,30 +135,30 @@ public class MdcHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> T callWithTenantAndUser0(final Callable<T> callable, final String tenant, final String user) throws Exception {
|
private static <T> T asTenantAsActor0(final String tenant, final String actor, final Callable<T> callable) throws Exception {
|
||||||
final String currentTenant = MDC.get(MDC_KEY_TENANT);
|
final String currentTenant = MDC.get(MDC_KEY_TENANT);
|
||||||
if (Objects.equals(currentTenant, tenant)) {
|
if (Objects.equals(currentTenant, tenant)) {
|
||||||
return callWithUser(callable, user);
|
return asActor(callable, actor);
|
||||||
} else {
|
} else {
|
||||||
put(MDC_KEY_TENANT, tenant);
|
put(MDC_KEY_TENANT, tenant);
|
||||||
try {
|
try {
|
||||||
return callWithUser(callable, user);
|
return asActor(callable, actor);
|
||||||
} finally {
|
} finally {
|
||||||
put(MDC_KEY_TENANT, currentTenant);
|
put(MDC_KEY_TENANT, currentTenant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> T callWithUser(final Callable<T> callable, final String user) throws Exception {
|
private static <T> T asActor(final Callable<T> callable, final String actor) throws Exception {
|
||||||
final String currentUser = MDC.get(MDC_KEY_USER);
|
final String currentActor = MDC.get(MDC_KEY_ACTOR);
|
||||||
if (Objects.equals(currentUser, user)) {
|
if (Objects.equals(currentActor, actor)) {
|
||||||
return callable.call();
|
return callable.call();
|
||||||
} else {
|
} else {
|
||||||
put(MDC_KEY_USER, user);
|
put(MDC_KEY_ACTOR, actor);
|
||||||
try {
|
try {
|
||||||
return callable.call();
|
return callable.call();
|
||||||
} finally {
|
} finally {
|
||||||
put(MDC_KEY_USER, currentUser);
|
put(MDC_KEY_ACTOR, currentActor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,14 +177,12 @@ public class MdcHandler {
|
|||||||
public static void addMdcFilter(final HttpSecurity httpSecurity) {
|
public static void addMdcFilter(final HttpSecurity httpSecurity) {
|
||||||
httpSecurity.addFilterBefore(new OncePerRequestFilter() {
|
httpSecurity.addFilterBefore(new OncePerRequestFilter() {
|
||||||
|
|
||||||
private final MdcHandler mdcFilter = MdcHandler.getInstance();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doFilterInternal(
|
protected void doFilterInternal(
|
||||||
final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain)
|
final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
try {
|
try {
|
||||||
mdcFilter.callWithAuth(() -> {
|
Mdc.withAuth(() -> {
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
@@ -12,7 +12,7 @@ package org.eclipse.hawkbit.exception;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define the Error codes for Error handling
|
* Define the error codes for error handling
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
public enum SpServerError {
|
public enum SpServerError {
|
||||||
@@ -182,9 +182,6 @@ public enum SpServerError {
|
|||||||
private final String key;
|
private final String key;
|
||||||
private final String message;
|
private final String message;
|
||||||
|
|
||||||
/**
|
|
||||||
* Repository side Error codes
|
|
||||||
*/
|
|
||||||
SpServerError(final String key, final String message) {
|
SpServerError(final String key, final String message) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ public class HawkbitSecurityProperties {
|
|||||||
*/
|
*/
|
||||||
private List<String> httpFirewallIgnoredPaths;
|
private List<String> httpFirewallIgnoredPaths;
|
||||||
/**
|
/**
|
||||||
* Basic authentication realm, see https://tools.ietf.org/html/rfc2617#page-3 .
|
* Basic auth realm, see https://tools.ietf.org/html/rfc2617#page-3 .
|
||||||
*/
|
*/
|
||||||
private String basicRealm = "hawkBit";
|
private String basicRealm = "hawkBit";
|
||||||
/**
|
/**
|
||||||
* If to allow http authentication when there is OAuth2 authentication enabled.
|
* If to allow http auth when there is OAuth2 auth enabled.
|
||||||
*/
|
*/
|
||||||
private boolean allowHttpBasicOnOAuthEnabled = false;
|
private boolean allowHttpBasicOnOAuthEnabled = false;
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ public class HawkbitSecurityProperties {
|
|||||||
|
|
||||||
public static final String X_FORWARDED_FOR = "X-Forwarded-For";
|
public static final String X_FORWARDED_FOR = "X-Forwarded-For";
|
||||||
/**
|
/**
|
||||||
* Blacklisted client (IP addresses) for for DDI and Management API.
|
* Blacklisted client (IP addresses) for DDI and Management API.
|
||||||
*/
|
*/
|
||||||
private String blacklist = "";
|
private String blacklist = "";
|
||||||
/**
|
/**
|
||||||
@@ -117,7 +117,7 @@ public class HawkbitSecurityProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Denial of service protection related properties.
|
* Denial-of-service (DoS) protection related properties.
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public static class Dos {
|
public static class Dos {
|
||||||
@@ -18,6 +18,7 @@ import io.micrometer.common.KeyValues;
|
|||||||
import io.micrometer.core.instrument.Tag;
|
import io.micrometer.core.instrument.Tag;
|
||||||
import io.micrometer.observation.ObservationRegistry;
|
import io.micrometer.observation.ObservationRegistry;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
|
import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
|
||||||
import org.springframework.boot.actuate.autoconfigure.observation.web.servlet.WebMvcObservationAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.observation.web.servlet.WebMvcObservationAutoConfiguration;
|
||||||
@@ -44,12 +45,6 @@ public class DefaultTenantConfiguration {
|
|||||||
|
|
||||||
public static final String TENANT_TAG = "tenant";
|
public static final String TENANT_TAG = "tenant";
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean
|
|
||||||
TenantAware.TenantResolver tenantResolver() {
|
|
||||||
return new TenantAware.DefaultTenantResolver();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
TenantAwareCacheManager cacheManager() {
|
TenantAwareCacheManager cacheManager() {
|
||||||
@@ -62,12 +57,12 @@ public class DefaultTenantConfiguration {
|
|||||||
@ConditionalOnProperty(name = "hawkbit.metrics.tenancy.web.enabled", havingValue = "true", matchIfMissing = true)
|
@ConditionalOnProperty(name = "hawkbit.metrics.tenancy.web.enabled", havingValue = "true", matchIfMissing = true)
|
||||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||||
@ConditionalOnClass(name = { "org.springframework.web.servlet.DispatcherServlet", "io.micrometer.observation.Observation" })
|
@ConditionalOnClass(name = { "org.springframework.web.servlet.DispatcherServlet", "io.micrometer.observation.Observation" })
|
||||||
@ConditionalOnBean({ ObservationRegistry.class, TenantAware.TenantResolver.class })
|
@ConditionalOnBean(ObservationRegistry.class)
|
||||||
public static class WebConfig {
|
public static class WebConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Primary
|
@Primary
|
||||||
public DefaultServerRequestObservationConvention serverRequestObservationConvention(final TenantAware.TenantResolver tenantResolver) {
|
public DefaultServerRequestObservationConvention serverRequestObservationConvention() {
|
||||||
return new DefaultServerRequestObservationConvention() {
|
return new DefaultServerRequestObservationConvention() {
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -78,7 +73,7 @@ public class DefaultTenantConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private KeyValue tenant() {
|
private KeyValue tenant() {
|
||||||
return KeyValue.of(TENANT_TAG, Optional.ofNullable(tenantResolver.resolveTenant()).orElse("n/a"));
|
return KeyValue.of(TENANT_TAG, Optional.ofNullable(AccessContext.tenant()).orElse("n/a"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -104,17 +99,16 @@ public class DefaultTenantConfiguration {
|
|||||||
@ConditionalOnClass(name = {
|
@ConditionalOnClass(name = {
|
||||||
"io.micrometer.core.instrument.Tag",
|
"io.micrometer.core.instrument.Tag",
|
||||||
"org.springframework.data.repository.core.support.RepositoryMethodInvocationListener" })
|
"org.springframework.data.repository.core.support.RepositoryMethodInvocationListener" })
|
||||||
@ConditionalOnBean(TenantAware.TenantResolver.class)
|
|
||||||
public static class RepositoryConfig {
|
public static class RepositoryConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public RepositoryTagsProvider repositoryTagsProvider(final TenantAware.TenantResolver tenantResolver) {
|
public RepositoryTagsProvider repositoryTagsProvider() {
|
||||||
return new DefaultRepositoryTagsProvider() {
|
return new DefaultRepositoryTagsProvider() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Tag> repositoryTags(final RepositoryMethodInvocationListener.RepositoryMethodInvocation invocation) {
|
public Iterable<Tag> repositoryTags(final RepositoryMethodInvocationListener.RepositoryMethodInvocation invocation) {
|
||||||
final Iterable<Tag> defaultTags = super.repositoryTags(invocation);
|
final Iterable<Tag> defaultTags = super.repositoryTags(invocation);
|
||||||
final String tenant = Optional.ofNullable(tenantResolver.resolveTenant()).orElse("n/a");
|
final String tenant = Optional.ofNullable(AccessContext.tenant()).orElse("n/a");
|
||||||
return () -> {
|
return () -> {
|
||||||
final Iterator<Tag> defaultTagsIterator = defaultTags.iterator();
|
final Iterator<Tag> defaultTagsIterator = defaultTags.iterator();
|
||||||
return new Iterator<>() {
|
return new Iterator<>() {
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made
|
|
||||||
* available under the terms of the Eclipse Public License 2.0
|
|
||||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
|
||||||
*/
|
|
||||||
package org.eclipse.hawkbit.tenancy;
|
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for components that are aware of the application's current tenant.
|
|
||||||
*/
|
|
||||||
public interface TenantAware {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation might retrieve the current tenant from a session or thread-local.
|
|
||||||
*
|
|
||||||
* @return the current tenant
|
|
||||||
*/
|
|
||||||
String getCurrentTenant();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the username of the currently logged-in user
|
|
||||||
*/
|
|
||||||
String getCurrentUsername();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gives the possibility to run a certain code under a specific given {@code tenant}. Only the given {@link Callable} is executed
|
|
||||||
* under the specific tenant e.g. under control of an {@link ThreadLocal}. After the {@link Callable} it must be ensured that the
|
|
||||||
* original tenant before this invocation is reset.
|
|
||||||
*
|
|
||||||
* @param tenant the tenant which the specific code should run
|
|
||||||
* @param callable the runner which is implemented to run this specific code under the given tenant
|
|
||||||
* @return the return type of the {@link Callable}
|
|
||||||
*/
|
|
||||||
<T> T runAsTenant(String tenant, Callable<T> callable);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gives the possibility to run a certain code under a specific given {@code tenant} and {@code username}.
|
|
||||||
* Only the given {@link Runnable} is executed under the specific tenant and user e.g. under control of an {@link ThreadLocal}.
|
|
||||||
* After the {@link Runnable} it must be ensured that the original tenant before this invocation is reset.
|
|
||||||
*
|
|
||||||
* @param tenant the tenant which the specific code should run with
|
|
||||||
* @param username the username which the specific code should run with
|
|
||||||
*/
|
|
||||||
void runAsTenantAsUser(String tenant, String username, Runnable runnable);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the tenant from the current context.
|
|
||||||
*/
|
|
||||||
interface TenantResolver {
|
|
||||||
|
|
||||||
String resolveTenant();
|
|
||||||
}
|
|
||||||
|
|
||||||
class DefaultTenantResolver implements TenantResolver {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String resolveTenant() {
|
|
||||||
final SecurityContext context = SecurityContextHolder.getContext();
|
|
||||||
if (context.getAuthentication() != null) {
|
|
||||||
final Object principal = context.getAuthentication().getPrincipal();
|
|
||||||
if (context.getAuthentication().getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareAuthenticationDetails) {
|
|
||||||
return tenantAwareAuthenticationDetails.tenant();
|
|
||||||
} else if (principal instanceof TenantAwareUser tenantAwareUser) {
|
|
||||||
return tenantAwareUser.getTenant();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,8 +15,8 @@ import java.io.Serializable;
|
|||||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An authentication details object {@link AbstractAuthenticationToken#getDetails()} which is stored in the
|
* An auth details object {@link AbstractAuthenticationToken#getDetails()} which is stored in the
|
||||||
* spring security authentication token details to transport the principal and tenant in the security context session.
|
* spring security auth token details to transport the principal and tenant in the security context session.
|
||||||
*/
|
*/
|
||||||
public record TenantAwareAuthenticationDetails(String tenant, boolean controller) implements Serializable {
|
public record TenantAwareAuthenticationDetails(String tenant, boolean controller) implements Serializable {
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware.TenantResolver;
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
@@ -34,7 +34,7 @@ import org.springframework.lang.Nullable;
|
|||||||
/**
|
/**
|
||||||
* A spring Cache Manager that handles the multi tenancy.
|
* A spring Cache Manager that handles the multi tenancy.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>If a tenant is resolved by the {@link TenantResolver}, a dedicated cache manager for that tenant is used/created.</li>
|
* <li>If a tenant is resolved by the {@link AccessContext}, a dedicated cache manager for that tenant is used/created.</li>
|
||||||
* <li>If no tenant is resolved, a global cache manager is used.</li>
|
* <li>If no tenant is resolved, a global cache manager is used.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@@ -50,7 +50,6 @@ public class TenantAwareCacheManager implements CacheManager {
|
|||||||
private CacheManager globalCacheManager;
|
private CacheManager globalCacheManager;
|
||||||
private final Map<String, CacheManager> tenant2CacheManager = new ConcurrentHashMap<>();
|
private final Map<String, CacheManager> tenant2CacheManager = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private TenantResolver resolver;
|
|
||||||
private Environment env;
|
private Environment env;
|
||||||
|
|
||||||
// default caffeine cache spec - see com.github.benmanes.caffeine.cache.CaffeineSpec javadoc for format details
|
// default caffeine cache spec - see com.github.benmanes.caffeine.cache.CaffeineSpec javadoc for format details
|
||||||
@@ -61,8 +60,7 @@ public class TenantAwareCacheManager implements CacheManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public void init(final TenantResolver resolver, final Environment env) {
|
public void init(final Environment env) {
|
||||||
this.resolver = resolver;
|
|
||||||
this.env = env;
|
this.env = env;
|
||||||
defaultSpec = env.resolvePlaceholders("${" + CONFIG_PREFIX + CONFIG_SPEC + ":expireAfterWrite=${hawkbit.cache.ttl:10s}}");
|
defaultSpec = env.resolvePlaceholders("${" + CONFIG_PREFIX + CONFIG_SPEC + ":expireAfterWrite=${hawkbit.cache.ttl:10s}}");
|
||||||
globalCacheManager = new TenantCacheManager(null);
|
globalCacheManager = new TenantCacheManager(null);
|
||||||
@@ -71,7 +69,7 @@ public class TenantAwareCacheManager implements CacheManager {
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Cache getCache(@NonNull final String name) {
|
public Cache getCache(@NonNull final String name) {
|
||||||
final Cache cache = Optional.ofNullable(resolver.resolveTenant())
|
final Cache cache = Optional.ofNullable(AccessContext.tenant())
|
||||||
.map(currentTenant -> tenant2CacheManager.computeIfAbsent(currentTenant, TenantCacheManager::new))
|
.map(currentTenant -> tenant2CacheManager.computeIfAbsent(currentTenant, TenantCacheManager::new))
|
||||||
.orElse(globalCacheManager)
|
.orElse(globalCacheManager)
|
||||||
.getCache(name);
|
.getCache(name);
|
||||||
@@ -81,7 +79,7 @@ public class TenantAwareCacheManager implements CacheManager {
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getCacheNames() {
|
public Collection<String> getCacheNames() {
|
||||||
final String currentTenant = resolver.resolveTenant();
|
final String currentTenant = AccessContext.tenant();
|
||||||
if (currentTenant == null) {
|
if (currentTenant == null) {
|
||||||
return globalCacheManager.getCacheNames();
|
return globalCacheManager.getCacheNames();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2020 Bosch.IO GmbH and others
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made
|
|
||||||
* available under the terms of the Eclipse Public License 2.0
|
|
||||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
|
||||||
*/
|
|
||||||
package org.eclipse.hawkbit.tenancy;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The service responsible for making the lookup for user authorities/roles based on his tenant and username
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface UserAuthoritiesResolver {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User authorities/roles lookup based on the username and the tenant context
|
|
||||||
*
|
|
||||||
* @param username The username of the user
|
|
||||||
* @return a {@link Collection} of authorities/roles for this user
|
|
||||||
*/
|
|
||||||
Collection<String> getUserAuthorities(String username);
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.util;
|
package org.eclipse.hawkbit.utils;
|
||||||
|
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@@ -7,16 +7,16 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.context;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.eclipse.hawkbit.security.SecurityContextSerializer.JSON_SERIALIZATION;
|
import static org.eclipse.hawkbit.context.AccessContext.withSecurityContext;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
import org.eclipse.hawkbit.auth.SpPermission;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
@@ -39,11 +39,12 @@ class SecurityContextSerializerTest {
|
|||||||
userPassAuthentication.setDetails(details);
|
userPassAuthentication.setDetails(details);
|
||||||
securityContext.setAuthentication(userPassAuthentication);
|
securityContext.setAuthentication(userPassAuthentication);
|
||||||
|
|
||||||
final String serialized = JSON_SERIALIZATION.serialize(securityContext);
|
final String serialized = serialize(securityContext);
|
||||||
final SecurityContext deserialized = JSON_SERIALIZATION.deserialize(serialized);
|
final SecurityContext deserialized = deserialize(serialized);
|
||||||
final Authentication authentication = deserialized.getAuthentication();
|
final Authentication authentication = deserialized.getAuthentication();
|
||||||
assertThat(SpringSecurityAuditorAware.resolveAuditor(authentication)).hasToString("user");
|
assertThat(resolve(authentication)).hasToString("user");
|
||||||
assertThat(authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet())).isEqualTo(AUTHORITIES);
|
assertThat(authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet()))
|
||||||
|
.isEqualTo(AUTHORITIES);
|
||||||
assertThat(authentication.isAuthenticated()).isTrue();
|
assertThat(authentication.isAuthenticated()).isTrue();
|
||||||
assertThat(authentication.getDetails()).isEqualTo(details);
|
assertThat(authentication.getDetails()).isEqualTo(details);
|
||||||
}
|
}
|
||||||
@@ -53,34 +54,16 @@ class SecurityContextSerializerTest {
|
|||||||
final SecurityContext securityContext = SecurityContextHolder.getContext();
|
final SecurityContext securityContext = SecurityContextHolder.getContext();
|
||||||
final UsernamePasswordAuthenticationToken userPassAuthentication = new UsernamePasswordAuthenticationToken(
|
final UsernamePasswordAuthenticationToken userPassAuthentication = new UsernamePasswordAuthenticationToken(
|
||||||
"FirstName.FamilyName@domain1.domain0.com",
|
"FirstName.FamilyName@domain1.domain0.com",
|
||||||
Map.of("should not be in" + bigString(10_000),"the output" + bigString(15_000)),
|
Map.of("should not be in" + bigString(10_000), "the output" + bigString(15_000)),
|
||||||
AUTHORITIES.stream().map(SimpleGrantedAuthority::new).toList());
|
AUTHORITIES.stream().map(SimpleGrantedAuthority::new).toList());
|
||||||
final TenantAwareAuthenticationDetails details = new TenantAwareAuthenticationDetails("my_test_enant", false);
|
final TenantAwareAuthenticationDetails details = new TenantAwareAuthenticationDetails("my_test_enant", false);
|
||||||
userPassAuthentication.setDetails(details);
|
userPassAuthentication.setDetails(details);
|
||||||
securityContext.setAuthentication(userPassAuthentication);
|
securityContext.setAuthentication(userPassAuthentication);
|
||||||
|
|
||||||
final String serialized = JSON_SERIALIZATION.serialize(securityContext);
|
final String serialized = serialize(securityContext);
|
||||||
assertThat(serialized).hasSizeLessThan(4096); // ensure that it is not too big
|
assertThat(serialized).hasSizeLessThan(4096); // ensure that it is not too big
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void testUsername() {
|
|
||||||
final SecurityContext securityContext = SecurityContextHolder.getContext();
|
|
||||||
final UsernamePasswordAuthenticationToken userPassAuthentication = new UsernamePasswordAuthenticationToken(
|
|
||||||
"user", null, AUTHORITIES.stream().map(SimpleGrantedAuthority::new).toList());
|
|
||||||
final TenantAwareAuthenticationDetails details = new TenantAwareAuthenticationDetails("my_tenant", false);
|
|
||||||
userPassAuthentication.setDetails(details);
|
|
||||||
securityContext.setAuthentication(userPassAuthentication);
|
|
||||||
|
|
||||||
final String serialized = JSON_SERIALIZATION.serialize(securityContext).replace("auditor", "username");
|
|
||||||
final SecurityContext deserialized = JSON_SERIALIZATION.deserialize(serialized);
|
|
||||||
final Authentication authentication = deserialized.getAuthentication();
|
|
||||||
assertThat(SpringSecurityAuditorAware.resolveAuditor(authentication)).hasToString("user");
|
|
||||||
assertThat(authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet())).isEqualTo(AUTHORITIES);
|
|
||||||
assertThat(authentication.isAuthenticated()).isTrue();
|
|
||||||
assertThat(authentication.getDetails()).isEqualTo(details);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String bigString(final int length) {
|
private static String bigString(final int length) {
|
||||||
final StringBuilder sb = new StringBuilder(length);
|
final StringBuilder sb = new StringBuilder(length);
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
@@ -88,4 +71,18 @@ class SecurityContextSerializerTest {
|
|||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String serialize(final SecurityContext securityContext) {
|
||||||
|
return withSecurityContext(securityContext, () -> AccessContext.securityContext().orElseThrow());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SecurityContext deserialize(final String serialized) {
|
||||||
|
return withSecurityContext(serialized, SecurityContextHolder::getContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String resolve(final Authentication authentication) {
|
||||||
|
final SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
|
||||||
|
securityContext.setAuthentication(authentication);
|
||||||
|
return withSecurityContext(securityContext, AccessContext::actor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Contributors to the Eclipse Foundation
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.context;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.context.AccessContext.asSystemAsTenant;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
|
import org.eclipse.hawkbit.auth.SpRole;
|
||||||
|
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
|
class SystemSecurityContextTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test() {
|
||||||
|
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("test", "pass", List.of(new SimpleGrantedAuthority("anonymous")));
|
||||||
|
auth.setDetails("string details");
|
||||||
|
test(auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testWithNullPrincipal() {
|
||||||
|
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(null, "pass", List.of(new SimpleGrantedAuthority("anonymous")));
|
||||||
|
auth.setDetails("string details");
|
||||||
|
test(auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testWithNullCredentials() {
|
||||||
|
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("test", null, List.of(new SimpleGrantedAuthority("anonymous")));
|
||||||
|
auth.setDetails("string details");
|
||||||
|
test(auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testWitAllNull() {
|
||||||
|
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(null, null, List.of(new SimpleGrantedAuthority("anonymous")));
|
||||||
|
auth.setDetails(null);
|
||||||
|
test(auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void test(final UsernamePasswordAuthenticationToken auth) {
|
||||||
|
final SecurityContext sc = SecurityContextHolder.createEmptyContext();
|
||||||
|
sc.setAuthentication(auth);
|
||||||
|
SecurityContextHolder.setContext(sc);
|
||||||
|
asSystemAsTenant("tenant", () -> {
|
||||||
|
final Authentication currentAuth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
Assertions.assertThat(currentAuth.getClass().getSimpleName()).isEqualTo("SystemCodeAuthentication");
|
||||||
|
Assertions.assertThat(currentAuth.getCredentials()).isNull();
|
||||||
|
Assertions.assertThat(currentAuth.getAuthorities()).isEqualTo(List.of(new SimpleGrantedAuthority(SpRole.SYSTEM_ROLE)));
|
||||||
|
Assertions.assertThat(currentAuth.getDetails()).isEqualTo(new TenantAwareAuthenticationDetails("tenant", false));
|
||||||
|
});
|
||||||
|
SecurityContextHolder.clearContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.auth.SpPermission;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,17 +21,18 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||||||
|
|
||||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties.Clients;
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties.Clients;
|
||||||
|
import org.eclipse.hawkbit.utils.IpUtil;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
/**
|
/**
|
||||||
* Feature: Unit Tests - Security<br/>
|
* Feature: Unit Tests - Security<br/>
|
||||||
* Story: IP Util Test
|
* Story: IP Util Test
|
||||||
*/
|
*/
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
class IpUtilTest {
|
class IpUtilTest {
|
||||||
|
|
||||||
private static final String X_FORWARDED_FOR = HawkbitSecurityProperties.Clients.X_FORWARDED_FOR;
|
private static final String X_FORWARDED_FOR = HawkbitSecurityProperties.Clients.X_FORWARDED_FOR;
|
||||||
@@ -68,7 +68,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -107,7 +107,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to " +
|
||||||
"be changed (i.e. read-only) or data volume restriction applies.",
|
"be changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -143,7 +143,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be" +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be" +
|
||||||
" changed (i.e. read-only) or data volume restriction applies.",
|
" changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -181,7 +181,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -244,7 +244,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json",
|
content = @Content(mediaType = "application/json",
|
||||||
schema = @Schema(implementation = ExceptionInfo.class))),
|
schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -289,7 +289,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -336,7 +336,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -377,7 +377,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -414,7 +414,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -474,7 +474,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
"""),
|
"""),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -516,7 +516,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
"""),
|
"""),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -565,7 +565,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
"the action awaiting confirmation in the same format as for the deploymentBase operation."),
|
"the action awaiting confirmation in the same format as for the deploymentBase operation."),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -607,7 +607,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -658,7 +658,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -701,7 +701,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -744,7 +744,7 @@ public interface DdiRootControllerRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) " +
|
||||||
"or data volume restriction applies.",
|
"or data volume restriction applies.",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import lombok.AccessLevel;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.eclipse.hawkbit.artifact.urlresolver.ArtifactUrlResolver;
|
import org.eclipse.hawkbit.artifact.urlresolver.ArtifactUrlResolver;
|
||||||
import org.eclipse.hawkbit.artifact.urlresolver.ArtifactUrlResolver.DownloadDescriptor;
|
import org.eclipse.hawkbit.artifact.urlresolver.ArtifactUrlResolver.DownloadDescriptor;
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiArtifact;
|
import org.eclipse.hawkbit.ddi.json.model.DdiArtifact;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiArtifactHash;
|
import org.eclipse.hawkbit.ddi.json.model.DdiArtifactHash;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiAutoConfirmationState;
|
import org.eclipse.hawkbit.ddi.json.model.DdiAutoConfirmationState;
|
||||||
@@ -34,7 +35,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
|||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
||||||
import org.eclipse.hawkbit.rest.json.model.ResponseList;
|
import org.eclipse.hawkbit.rest.json.model.ResponseList;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
|
||||||
import org.springframework.hateoas.Link;
|
import org.springframework.hateoas.Link;
|
||||||
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
|
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
|
||||||
import org.springframework.http.HttpRequest;
|
import org.springframework.http.HttpRequest;
|
||||||
@@ -47,25 +47,24 @@ import org.springframework.util.CollectionUtils;
|
|||||||
public final class DataConversionHelper {
|
public final class DataConversionHelper {
|
||||||
|
|
||||||
public static DdiConfirmationBase createConfirmationBase(
|
public static DdiConfirmationBase createConfirmationBase(
|
||||||
final Target target, final Action activeAction,
|
final Target target, final Action activeAction, final DdiAutoConfirmationState autoConfirmationState) {
|
||||||
final DdiAutoConfirmationState autoConfirmationState, final TenantAware tenantAware) {
|
|
||||||
final String controllerId = target.getControllerId();
|
final String controllerId = target.getControllerId();
|
||||||
final DdiConfirmationBase confirmationBase = new DdiConfirmationBase(autoConfirmationState);
|
final DdiConfirmationBase confirmationBase = new DdiConfirmationBase(autoConfirmationState);
|
||||||
if (autoConfirmationState.isActive()) {
|
if (autoConfirmationState.isActive()) {
|
||||||
confirmationBase.add(WebMvcLinkBuilder
|
confirmationBase.add(WebMvcLinkBuilder
|
||||||
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, AccessContext.tenant())
|
||||||
.deactivateAutoConfirmation(tenantAware.getCurrentTenant(), controllerId))
|
.deactivateAutoConfirmation(AccessContext.tenant(), controllerId))
|
||||||
.withRel(DdiRestConstants.AUTO_CONFIRM_DEACTIVATE).expand());
|
.withRel(DdiRestConstants.AUTO_CONFIRM_DEACTIVATE).expand());
|
||||||
} else {
|
} else {
|
||||||
confirmationBase.add(WebMvcLinkBuilder
|
confirmationBase.add(WebMvcLinkBuilder
|
||||||
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, AccessContext.tenant())
|
||||||
.activateAutoConfirmation(tenantAware.getCurrentTenant(), controllerId, null))
|
.activateAutoConfirmation(AccessContext.tenant(), controllerId, null))
|
||||||
.withRel(DdiRestConstants.AUTO_CONFIRM_ACTIVATE).expand());
|
.withRel(DdiRestConstants.AUTO_CONFIRM_ACTIVATE).expand());
|
||||||
}
|
}
|
||||||
if (activeAction != null && activeAction.isWaitingConfirmation()) {
|
if (activeAction != null && activeAction.isWaitingConfirmation()) {
|
||||||
confirmationBase.add(WebMvcLinkBuilder
|
confirmationBase.add(WebMvcLinkBuilder
|
||||||
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, AccessContext.tenant())
|
||||||
.getConfirmationBaseAction(tenantAware.getCurrentTenant(), controllerId,
|
.getConfirmationBaseAction(AccessContext.tenant(), controllerId,
|
||||||
activeAction.getId(), calculateEtag(activeAction), null))
|
activeAction.getId(), calculateEtag(activeAction), null))
|
||||||
.withRel(DdiRestConstants.CONFIRMATION_BASE).expand());
|
.withRel(DdiRestConstants.CONFIRMATION_BASE).expand());
|
||||||
}
|
}
|
||||||
@@ -75,22 +74,22 @@ public final class DataConversionHelper {
|
|||||||
|
|
||||||
public static DdiControllerBase fromTarget(
|
public static DdiControllerBase fromTarget(
|
||||||
final Target target, final Action installedAction,
|
final Target target, final Action installedAction,
|
||||||
final Action activeAction, final String defaultControllerPollTime, final TenantAware tenantAware) {
|
final Action activeAction, final String defaultControllerPollTime) {
|
||||||
final DdiControllerBase result = new DdiControllerBase(
|
final DdiControllerBase result = new DdiControllerBase(
|
||||||
new DdiConfig(new DdiPolling(defaultControllerPollTime)));
|
new DdiConfig(new DdiPolling(defaultControllerPollTime)));
|
||||||
|
|
||||||
if (activeAction != null) {
|
if (activeAction != null) {
|
||||||
if (activeAction.isWaitingConfirmation()) {
|
if (activeAction.isWaitingConfirmation()) {
|
||||||
result.add(WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder
|
result.add(WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder
|
||||||
.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
.methodOn(DdiRootController.class, AccessContext.tenant())
|
||||||
.getConfirmationBaseAction(tenantAware.getCurrentTenant(), target.getControllerId(),
|
.getConfirmationBaseAction(AccessContext.tenant(), target.getControllerId(),
|
||||||
activeAction.getId(), calculateEtag(activeAction), null))
|
activeAction.getId(), calculateEtag(activeAction), null))
|
||||||
.withRel(DdiRestConstants.CONFIRMATION_BASE).expand());
|
.withRel(DdiRestConstants.CONFIRMATION_BASE).expand());
|
||||||
|
|
||||||
} else if (activeAction.isCancelingOrCanceled()) {
|
} else if (activeAction.isCancelingOrCanceled()) {
|
||||||
result.add(WebMvcLinkBuilder
|
result.add(WebMvcLinkBuilder
|
||||||
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, AccessContext.tenant())
|
||||||
.getControllerCancelAction(tenantAware.getCurrentTenant(), target.getControllerId(),
|
.getControllerCancelAction(AccessContext.tenant(), target.getControllerId(),
|
||||||
activeAction.getId()))
|
activeAction.getId()))
|
||||||
.withRel(DdiRestConstants.CANCEL_ACTION).expand());
|
.withRel(DdiRestConstants.CANCEL_ACTION).expand());
|
||||||
} else {
|
} else {
|
||||||
@@ -98,9 +97,9 @@ public final class DataConversionHelper {
|
|||||||
// have changed from 'soft' to 'forced' type, and we need to change the payload of the
|
// have changed from 'soft' to 'forced' type, and we need to change the payload of the
|
||||||
// response because of eTags.
|
// response because of eTags.
|
||||||
result.add(WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder
|
result.add(WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder
|
||||||
.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
.methodOn(DdiRootController.class, AccessContext.tenant())
|
||||||
.getControllerDeploymentBaseAction(
|
.getControllerDeploymentBaseAction(
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(),
|
AccessContext.tenant(), target.getControllerId(),
|
||||||
activeAction.getId(), calculateEtag(activeAction), null))
|
activeAction.getId(), calculateEtag(activeAction), null))
|
||||||
.withRel(DdiRestConstants.DEPLOYMENT_BASE_ACTION).expand());
|
.withRel(DdiRestConstants.DEPLOYMENT_BASE_ACTION).expand());
|
||||||
}
|
}
|
||||||
@@ -109,8 +108,8 @@ public final class DataConversionHelper {
|
|||||||
if (installedAction != null && !installedAction.isActive()) {
|
if (installedAction != null && !installedAction.isActive()) {
|
||||||
result.add(
|
result.add(
|
||||||
WebMvcLinkBuilder
|
WebMvcLinkBuilder
|
||||||
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, AccessContext.tenant())
|
||||||
.getControllerInstalledAction(tenantAware.getCurrentTenant(),
|
.getControllerInstalledAction(AccessContext.tenant(),
|
||||||
target.getControllerId(), installedAction.getId(), null))
|
target.getControllerId(), installedAction.getId(), null))
|
||||||
.withRel(DdiRestConstants.INSTALLED_BASE_ACTION).expand());
|
.withRel(DdiRestConstants.INSTALLED_BASE_ACTION).expand());
|
||||||
}
|
}
|
||||||
@@ -118,9 +117,9 @@ public final class DataConversionHelper {
|
|||||||
if (target.isRequestControllerAttributes()) {
|
if (target.isRequestControllerAttributes()) {
|
||||||
result.add(WebMvcLinkBuilder
|
result.add(WebMvcLinkBuilder
|
||||||
.linkTo(WebMvcLinkBuilder
|
.linkTo(WebMvcLinkBuilder
|
||||||
.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
.methodOn(DdiRootController.class, AccessContext.tenant())
|
||||||
// doesn't really call the putConfigData with null, just create the link
|
// doesn't really call the putConfigData with null, just create the link
|
||||||
.putConfigData(null, tenantAware.getCurrentTenant(), target.getControllerId()))
|
.putConfigData(null, AccessContext.tenant(), target.getControllerId()))
|
||||||
.withRel(DdiRestConstants.CONFIG_DATA_ACTION).expand());
|
.withRel(DdiRestConstants.CONFIG_DATA_ACTION).expand());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.eclipse.hawkbit.artifact.model.ArtifactStream;
|
import org.eclipse.hawkbit.artifact.model.ArtifactStream;
|
||||||
import org.eclipse.hawkbit.artifact.urlresolver.ArtifactUrlResolver;
|
import org.eclipse.hawkbit.artifact.urlresolver.ArtifactUrlResolver;
|
||||||
import org.eclipse.hawkbit.audit.AuditLog;
|
import org.eclipse.hawkbit.audit.AuditLog;
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiActionFeedback;
|
import org.eclipse.hawkbit.ddi.json.model.DdiActionFeedback;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiActionHistory;
|
import org.eclipse.hawkbit.ddi.json.model.DdiActionHistory;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiActivateAutoConfirmation;
|
import org.eclipse.hawkbit.ddi.json.model.DdiActivateAutoConfirmation;
|
||||||
@@ -68,8 +69,7 @@ import org.eclipse.hawkbit.rest.util.FileStreamingUtil;
|
|||||||
import org.eclipse.hawkbit.rest.util.HttpUtil;
|
import org.eclipse.hawkbit.rest.util.HttpUtil;
|
||||||
import org.eclipse.hawkbit.rest.util.RequestResponseContextHolder;
|
import org.eclipse.hawkbit.rest.util.RequestResponseContextHolder;
|
||||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.utils.IpUtil;
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
@@ -102,7 +102,6 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
private final SystemManagement systemManagement;
|
private final SystemManagement systemManagement;
|
||||||
private final ApplicationEventPublisher eventPublisher;
|
private final ApplicationEventPublisher eventPublisher;
|
||||||
private final HawkbitSecurityProperties securityProperties;
|
private final HawkbitSecurityProperties securityProperties;
|
||||||
private final TenantAware tenantAware;
|
|
||||||
|
|
||||||
@SuppressWarnings("java:S107")
|
@SuppressWarnings("java:S107")
|
||||||
public DdiRootController(
|
public DdiRootController(
|
||||||
@@ -110,7 +109,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
final ArtifactManagement artifactManagement, final ArtifactUrlResolver artifactUrlHandler,
|
final ArtifactManagement artifactManagement, final ArtifactUrlResolver artifactUrlHandler,
|
||||||
final SystemManagement systemManagement,
|
final SystemManagement systemManagement,
|
||||||
final ApplicationEventPublisher eventPublisher,
|
final ApplicationEventPublisher eventPublisher,
|
||||||
final HawkbitSecurityProperties securityProperties, final TenantAware tenantAware) {
|
final HawkbitSecurityProperties securityProperties) {
|
||||||
this.controllerManagement = controllerManagement;
|
this.controllerManagement = controllerManagement;
|
||||||
this.confirmationManagement = confirmationManagement;
|
this.confirmationManagement = confirmationManagement;
|
||||||
this.artifactManagement = artifactManagement;
|
this.artifactManagement = artifactManagement;
|
||||||
@@ -118,7 +117,6 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
this.systemManagement = systemManagement;
|
this.systemManagement = systemManagement;
|
||||||
this.eventPublisher = eventPublisher;
|
this.eventPublisher = eventPublisher;
|
||||||
this.securityProperties = securityProperties;
|
this.securityProperties = securityProperties;
|
||||||
this.tenantAware = tenantAware;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -155,7 +153,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
installedAction, activeAction,
|
installedAction, activeAction,
|
||||||
activeAction == null
|
activeAction == null
|
||||||
? controllerManagement.getPollingTime(target)
|
? controllerManagement.getPollingTime(target)
|
||||||
: controllerManagement.getPollingTimeForAction(target, activeAction), tenantAware),
|
: controllerManagement.getPollingTimeForAction(target, activeAction)),
|
||||||
HttpStatus.OK);
|
HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +188,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
(length, shippedSinceLastEvent, total) -> {
|
(length, shippedSinceLastEvent, total) -> {
|
||||||
if (actionStatus != null) {
|
if (actionStatus != null) {
|
||||||
eventPublisher.publishEvent(new DownloadProgressEvent(
|
eventPublisher.publishEvent(new DownloadProgressEvent(
|
||||||
tenantAware.getCurrentTenant(), actionStatus.getId(), shippedSinceLastEvent));
|
AccessContext.tenant(), actionStatus.getId(), shippedSinceLastEvent));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -352,14 +350,13 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
@Override
|
@Override
|
||||||
public ResponseEntity<DdiConfirmationBase> getConfirmationBase(final String tenant, final String controllerId) {
|
public ResponseEntity<DdiConfirmationBase> getConfirmationBase(final String tenant, final String controllerId) {
|
||||||
log.debug("getConfirmationBase is called [controllerId={}].", controllerId);
|
log.debug("getConfirmationBase is called [controllerId={}].", controllerId);
|
||||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId, IpUtil
|
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist(
|
||||||
.getClientIpFromRequest(RequestResponseContextHolder.getHttpServletRequest(), securityProperties));
|
controllerId, IpUtil.getClientIpFromRequest(RequestResponseContextHolder.getHttpServletRequest(), securityProperties));
|
||||||
final Action activeAction = controllerManagement.findActiveActionWithHighestWeight(controllerId).orElse(null);
|
final Action activeAction = controllerManagement.findActiveActionWithHighestWeight(controllerId).orElse(null);
|
||||||
|
|
||||||
final DdiAutoConfirmationState autoConfirmationState = getAutoConfirmationState(controllerId);
|
final DdiAutoConfirmationState autoConfirmationState = getAutoConfirmationState(controllerId);
|
||||||
|
|
||||||
final DdiConfirmationBase confirmationBase = DataConversionHelper.createConfirmationBase(
|
final DdiConfirmationBase confirmationBase = DataConversionHelper.createConfirmationBase(target, activeAction, autoConfirmationState);
|
||||||
target, activeAction, autoConfirmationState, tenantAware);
|
|
||||||
return new ResponseEntity<>(confirmationBase, HttpStatus.OK);
|
return new ResponseEntity<>(confirmationBase, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
|
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
|
||||||
import com.fasterxml.jackson.dataformat.cbor.CBORGenerator;
|
import com.fasterxml.jackson.dataformat.cbor.CBORGenerator;
|
||||||
import com.fasterxml.jackson.dataformat.cbor.CBORParser;
|
import com.fasterxml.jackson.dataformat.cbor.CBORParser;
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiActionFeedback;
|
import org.eclipse.hawkbit.ddi.json.model.DdiActionFeedback;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiAssignedVersion;
|
import org.eclipse.hawkbit.ddi.json.model.DdiAssignedVersion;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiConfirmationFeedback;
|
import org.eclipse.hawkbit.ddi.json.model.DdiConfirmationFeedback;
|
||||||
@@ -131,7 +132,7 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
|||||||
|
|
||||||
protected ResultActions putInstalledBase(final String controllerId, final String content, final ResultMatcher statusMatcher)
|
protected ResultActions putInstalledBase(final String controllerId, final String content, final ResultMatcher statusMatcher)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return mvc.perform(put(INSTALLED_BASE_ROOT, tenantAware.getCurrentTenant(), controllerId)
|
return mvc.perform(put(INSTALLED_BASE_ROOT, AccessContext.tenant(), controllerId)
|
||||||
.content(content.getBytes()).contentType(MediaType.APPLICATION_JSON))
|
.content(content.getBytes()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(statusMatcher);
|
.andExpect(statusMatcher);
|
||||||
@@ -141,7 +142,7 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
|||||||
final MediaType mediaType, final String controllerId,
|
final MediaType mediaType, final String controllerId,
|
||||||
final Long actionId, final byte[] content, final ResultMatcher statusMatcher) throws Exception {
|
final Long actionId, final byte[] content, final ResultMatcher statusMatcher) throws Exception {
|
||||||
return mvc
|
return mvc
|
||||||
.perform(post(DEPLOYMENT_FEEDBACK, tenantAware.getCurrentTenant(), controllerId, actionId)
|
.perform(post(DEPLOYMENT_FEEDBACK, AccessContext.tenant(), controllerId, actionId)
|
||||||
.content(content).contentType(mediaType).accept(mediaType))
|
.content(content).contentType(mediaType).accept(mediaType))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(statusMatcher);
|
.andExpect(statusMatcher);
|
||||||
@@ -157,7 +158,7 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
|||||||
final MediaType mediaType, final String controllerId,
|
final MediaType mediaType, final String controllerId,
|
||||||
final Long actionId, final byte[] content, final ResultMatcher statusMatcher) throws Exception {
|
final Long actionId, final byte[] content, final ResultMatcher statusMatcher) throws Exception {
|
||||||
return mvc
|
return mvc
|
||||||
.perform(post(CANCEL_FEEDBACK, tenantAware.getCurrentTenant(), controllerId, actionId).content(content)
|
.perform(post(CANCEL_FEEDBACK, AccessContext.tenant(), controllerId, actionId).content(content)
|
||||||
.contentType(mediaType).accept(mediaType))
|
.contentType(mediaType).accept(mediaType))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(statusMatcher);
|
.andExpect(statusMatcher);
|
||||||
@@ -177,7 +178,7 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
|||||||
final DistributionSet ds, final Artifact artifact, final Artifact artifactSignature, final Long actionId,
|
final DistributionSet ds, final Artifact artifact, final Artifact artifactSignature, final Long actionId,
|
||||||
final Long osModuleId, final String downloadType, final String updateType) throws Exception {
|
final Long osModuleId, final String downloadType, final String updateType) throws Exception {
|
||||||
final ResultActions resultActions = performGet(DEPLOYMENT_BASE, mediaType, status().isOk(),
|
final ResultActions resultActions = performGet(DEPLOYMENT_BASE, mediaType, status().isOk(),
|
||||||
tenantAware.getCurrentTenant(), controllerId, actionId.toString());
|
AccessContext.tenant(), controllerId, actionId.toString());
|
||||||
return verifyBasePayload(
|
return verifyBasePayload(
|
||||||
"$.deployment", resultActions, controllerId, ds, artifact, artifactSignature, actionId, osModuleId, downloadType, updateType);
|
"$.deployment", resultActions, controllerId, ds, artifact, artifactSignature, actionId, osModuleId, downloadType, updateType);
|
||||||
}
|
}
|
||||||
@@ -194,18 +195,18 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
|||||||
final DistributionSet ds, final Artifact artifact, final Artifact artifactSignature, final Long actionId,
|
final DistributionSet ds, final Artifact artifact, final Artifact artifactSignature, final Long actionId,
|
||||||
final Long osModuleId, final Action.ActionType actionType) throws Exception {
|
final Long osModuleId, final Action.ActionType actionType) throws Exception {
|
||||||
final ResultActions resultActions = performGet(INSTALLED_BASE, mediaType, status().isOk(),
|
final ResultActions resultActions = performGet(INSTALLED_BASE, mediaType, status().isOk(),
|
||||||
tenantAware.getCurrentTenant(), controllerId, actionId.toString());
|
AccessContext.tenant(), controllerId, actionId.toString());
|
||||||
return verifyBasePayload("$.deployment", resultActions, controllerId, ds, artifact, artifactSignature, actionId, osModuleId,
|
return verifyBasePayload("$.deployment", resultActions, controllerId, ds, artifact, artifactSignature, actionId, osModuleId,
|
||||||
getDownloadAndUploadType(actionType), getDownloadAndUploadType(actionType));
|
getDownloadAndUploadType(actionType), getDownloadAndUploadType(actionType));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String installedBaseLink(final String controllerId, final String actionId) {
|
protected String installedBaseLink(final String controllerId, final String actionId) {
|
||||||
return HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" +
|
return HTTP_LOCALHOST + AccessContext.tenant() + "/controller/v1/" +
|
||||||
controllerId + "/installedBase/" + actionId;
|
controllerId + "/installedBase/" + actionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String deploymentBaseLink(final String controllerId, final String actionId) {
|
protected String deploymentBaseLink(final String controllerId, final String actionId) {
|
||||||
return HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" +
|
return HTTP_LOCALHOST + AccessContext.tenant() + "/controller/v1/" +
|
||||||
controllerId + "/deploymentBase/" + actionId;
|
controllerId + "/deploymentBase/" + actionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +320,7 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
|||||||
final Long osModuleId, final String downloadType, final String updateType) throws Exception {
|
final Long osModuleId, final String downloadType, final String updateType) throws Exception {
|
||||||
final ResultActions resultActions = performGet(
|
final ResultActions resultActions = performGet(
|
||||||
CONFIRMATION_BASE_ACTION, mediaType, status().isOk(),
|
CONFIRMATION_BASE_ACTION, mediaType, status().isOk(),
|
||||||
tenantAware.getCurrentTenant(), controllerId, actionId.toString());
|
AccessContext.tenant(), controllerId, actionId.toString());
|
||||||
return verifyBasePayload(
|
return verifyBasePayload(
|
||||||
"$.confirmation", resultActions, controllerId, ds, artifact, artifactSignature, actionId, osModuleId,
|
"$.confirmation", resultActions, controllerId, ds, artifact, artifactSignature, actionId, osModuleId,
|
||||||
downloadType, updateType);
|
downloadType, updateType);
|
||||||
@@ -367,10 +368,10 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
|||||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[0].hashes.sha256",
|
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[0].hashes.sha256",
|
||||||
contains(artifact.getSha256Hash())))
|
contains(artifact.getSha256Hash())))
|
||||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[0]._links.download-http.href",
|
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[0]._links.download-http.href",
|
||||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId +
|
contains(HTTP_LOCALHOST + AccessContext.tenant() + "/controller/v1/" + controllerId +
|
||||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifact.getFilename())))
|
"/softwaremodules/" + osModuleId + "/artifacts/" + artifact.getFilename())))
|
||||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[0]._links.md5sum-http.href",
|
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[0]._links.md5sum-http.href",
|
||||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId +
|
contains(HTTP_LOCALHOST + AccessContext.tenant() + "/controller/v1/" + controllerId +
|
||||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifact.getFilename() + ".MD5SUM")))
|
"/softwaremodules/" + osModuleId + "/artifacts/" + artifact.getFilename() + ".MD5SUM")))
|
||||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1].size", contains(ARTIFACT_SIZE)))
|
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1].size", contains(ARTIFACT_SIZE)))
|
||||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1].filename",
|
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1].filename",
|
||||||
@@ -382,10 +383,10 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
|||||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1].hashes.sha256",
|
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1].hashes.sha256",
|
||||||
contains(artifactSignature.getSha256Hash())))
|
contains(artifactSignature.getSha256Hash())))
|
||||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1]._links.download-http.href",
|
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1]._links.download-http.href",
|
||||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId +
|
contains(HTTP_LOCALHOST + AccessContext.tenant() + "/controller/v1/" + controllerId +
|
||||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifactSignature.getFilename())))
|
"/softwaremodules/" + osModuleId + "/artifacts/" + artifactSignature.getFilename())))
|
||||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1]._links.md5sum-http.href",
|
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1]._links.md5sum-http.href",
|
||||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId +
|
contains(HTTP_LOCALHOST + AccessContext.tenant() + "/controller/v1/" + controllerId +
|
||||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifactSignature.getFilename() + ".MD5SUM")))
|
"/softwaremodules/" + osModuleId + "/artifacts/" + artifactSignature.getFilename() + ".MD5SUM")))
|
||||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='bApp')].version",
|
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='bApp')].version",
|
||||||
contains(findFirstModuleByType(ds, appType).orElseThrow().getVersion())))
|
contains(findFirstModuleByType(ds, appType).orElseThrow().getVersion())))
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.ddi.rest.resource.DdiArtifactDownloadTest.DownloadTestConfiguration;
|
import org.eclipse.hawkbit.ddi.rest.resource.DdiArtifactDownloadTest.DownloadTestConfiguration;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.DownloadProgressEvent;
|
import org.eclipse.hawkbit.repository.event.remote.DownloadProgressEvent;
|
||||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||||
@@ -106,55 +107,55 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// test now consistent data to test allowed methods
|
// test now consistent data to test allowed methods
|
||||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
mvc.perform(get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename())
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename())
|
||||||
.header(HttpHeaders.IF_MATCH, artifact.getSha1Hash()))
|
.header(HttpHeaders.IF_MATCH, artifact.getSha1Hash()))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
mvc.perform(get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
// test failed If-match
|
// test failed If-match
|
||||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
mvc.perform(get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename())
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename())
|
||||||
.header(HttpHeaders.IF_MATCH, "fsjkhgjfdhg"))
|
.header(HttpHeaders.IF_MATCH, "fsjkhgjfdhg"))
|
||||||
.andExpect(status().isPreconditionFailed());
|
.andExpect(status().isPreconditionFailed());
|
||||||
|
|
||||||
// test invalid range
|
// test invalid range
|
||||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
mvc.perform(get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename())
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename())
|
||||||
.header("Range", "bytes=1-10,hdsfjksdh"))
|
.header("Range", "bytes=1-10,hdsfjksdh"))
|
||||||
.andExpect(header().string("Content-Range", "bytes */" + 5 * 1024))
|
.andExpect(header().string("Content-Range", "bytes */" + 5 * 1024))
|
||||||
.andExpect(status().isRequestedRangeNotSatisfiable());
|
.andExpect(status().isRequestedRangeNotSatisfiable());
|
||||||
|
|
||||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
mvc.perform(get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename())
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename())
|
||||||
.header("Range", "bytes=100-10"))
|
.header("Range", "bytes=100-10"))
|
||||||
.andExpect(header().string("Content-Range", "bytes */" + 5 * 1024))
|
.andExpect(header().string("Content-Range", "bytes */" + 5 * 1024))
|
||||||
.andExpect(status().isRequestedRangeNotSatisfiable());
|
.andExpect(status().isRequestedRangeNotSatisfiable());
|
||||||
|
|
||||||
// not allowed methods
|
// not allowed methods
|
||||||
mvc.perform(put("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
mvc.perform(put("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(delete("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
mvc.perform(delete("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(post("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
mvc.perform(post("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(put("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
mvc.perform(put("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(delete("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
mvc.perform(delete("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(post("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
mvc.perform(post("/{tenant}/controller/v1/{controllerId}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +194,7 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
|||||||
assignDistributionSet(ds, targets);
|
assignDistributionSet(ds, targets);
|
||||||
final MvcResult result = mvc.perform(get(
|
final MvcResult result = mvc.perform(get(
|
||||||
"/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
"/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
|
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
|
||||||
.andExpect(header().string("Accept-Ranges", "bytes"))
|
.andExpect(header().string("Accept-Ranges", "bytes"))
|
||||||
@@ -233,7 +234,7 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// download
|
// download
|
||||||
final MvcResult result = mvc.perform(get(
|
final MvcResult result = mvc.perform(get(
|
||||||
"/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}.MD5SUM",
|
"/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}.MD5SUM",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), artifact.getFilename()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(header().string("Content-Disposition",
|
.andExpect(header().string("Content-Disposition",
|
||||||
"attachment;filename=" + artifact.getFilename() + ".MD5SUM"))
|
"attachment;filename=" + artifact.getFilename() + ".MD5SUM"))
|
||||||
@@ -278,7 +279,7 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
final MvcResult result = mvc.perform(get(
|
final MvcResult result = mvc.perform(get(
|
||||||
"/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
"/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), "file1").header("Range",
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), "file1").header("Range",
|
||||||
"bytes=" + rangeString))
|
"bytes=" + rangeString))
|
||||||
.andExpect(status().isPartialContent())
|
.andExpect(status().isPartialContent())
|
||||||
.andExpect(header().string("ETag", artifact.getSha1Hash()))
|
.andExpect(header().string("ETag", artifact.getSha1Hash()))
|
||||||
@@ -298,7 +299,7 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// return last 1000 Bytes
|
// return last 1000 Bytes
|
||||||
MvcResult result = mvc.perform(
|
MvcResult result = mvc.perform(
|
||||||
get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), "file1")
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), "file1")
|
||||||
.header("Range", "bytes=-1000"))
|
.header("Range", "bytes=-1000"))
|
||||||
.andExpect(status().isPartialContent())
|
.andExpect(status().isPartialContent())
|
||||||
.andExpect(header().string("ETag", artifact.getSha1Hash()))
|
.andExpect(header().string("ETag", artifact.getSha1Hash()))
|
||||||
@@ -317,7 +318,7 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// skip first 1000 Bytes and return the rest
|
// skip first 1000 Bytes and return the rest
|
||||||
result = mvc.perform(
|
result = mvc.perform(
|
||||||
get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), "file1")
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), "file1")
|
||||||
.header("Range", "bytes=1000-"))
|
.header("Range", "bytes=1000-"))
|
||||||
.andExpect(status().isPartialContent())
|
.andExpect(status().isPartialContent())
|
||||||
.andExpect(header().string("ETag", artifact.getSha1Hash()))
|
.andExpect(header().string("ETag", artifact.getSha1Hash()))
|
||||||
@@ -335,7 +336,7 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// Start download from file end fails
|
// Start download from file end fails
|
||||||
mvc.perform(
|
mvc.perform(
|
||||||
get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), "file1")
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), "file1")
|
||||||
.header("Range", "bytes=" + random.length + "-"))
|
.header("Range", "bytes=" + random.length + "-"))
|
||||||
.andExpect(status().isRequestedRangeNotSatisfiable())
|
.andExpect(status().isRequestedRangeNotSatisfiable())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
|
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
|
||||||
@@ -347,7 +348,7 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// multipart download - first 20 bytes in 2 parts
|
// multipart download - first 20 bytes in 2 parts
|
||||||
result = mvc.perform(
|
result = mvc.perform(
|
||||||
get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
get("/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), getOsModule(ds), "file1")
|
AccessContext.tenant(), target.getControllerId(), getOsModule(ds), "file1")
|
||||||
.header("Range", "bytes=0-9,10-19"))
|
.header("Range", "bytes=0-9,10-19"))
|
||||||
.andExpect(status().isPartialContent())
|
.andExpect(status().isPartialContent())
|
||||||
.andExpect(header().string("ETag", artifact.getSha1Hash()))
|
.andExpect(header().string("ETag", artifact.getSha1Hash()))
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
|
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
|
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
|
||||||
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
||||||
@@ -66,7 +67,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// check that we can get the cancel action as CBOR
|
// check that we can get the cancel action as CBOR
|
||||||
final byte[] result = mvc
|
final byte[] result = mvc
|
||||||
.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId(), tenantAware.getCurrentTenant())
|
+ cancelAction.getId(), AccessContext.tenant())
|
||||||
.accept(DdiRestConstants.MEDIA_TYPE_CBOR))
|
.accept(DdiRestConstants.MEDIA_TYPE_CBOR))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -80,7 +81,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// and submit feedback as CBOR
|
// and submit feedback as CBOR
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(jsonToCbor(getJsonProceedingCancelActionFeedback()))
|
.content(jsonToCbor(getJsonProceedingCancelActionFeedback()))
|
||||||
.contentType(DdiRestConstants.MEDIA_TYPE_CBOR).accept(DdiRestConstants.MEDIA_TYPE_CBOR))
|
.contentType(DdiRestConstants.MEDIA_TYPE_CBOR).accept(DdiRestConstants.MEDIA_TYPE_CBOR))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -104,7 +105,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// controller rejects cancellation
|
// controller rejects cancellation
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonRejectedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonRejectedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -115,7 +116,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// get update action anyway
|
// get update action anyway
|
||||||
mvc.perform(
|
mvc.perform(
|
||||||
get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/" + actionId,
|
get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/" + actionId,
|
||||||
tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON))
|
AccessContext.tenant()).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||||
@@ -131,7 +132,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// and finish it
|
// and finish it
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/"
|
||||||
+ actionId + "/feedback", tenantAware.getCurrentTenant()).content(
|
+ actionId + "/feedback", AccessContext.tenant()).content(
|
||||||
getJsonActionFeedback(DdiStatus.ExecutionStatus.CLOSED, DdiResult.FinalResult.NONE,
|
getJsonActionFeedback(DdiStatus.ExecutionStatus.CLOSED, DdiResult.FinalResult.NONE,
|
||||||
Collections.singletonList("message")))
|
Collections.singletonList("message")))
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
@@ -161,14 +162,14 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
||||||
|
|
||||||
final long timeBeforeFirstPoll = System.currentTimeMillis();
|
final long timeBeforeFirstPoll = System.currentTimeMillis();
|
||||||
mvc.perform(get("/{tenant}/controller/v1/{controller}", tenantAware.getCurrentTenant(),
|
mvc.perform(get("/{tenant}/controller/v1/{controller}", AccessContext.tenant(),
|
||||||
TestdataFactory.DEFAULT_CONTROLLER_ID).accept(MediaTypes.HAL_JSON))
|
TestdataFactory.DEFAULT_CONTROLLER_ID).accept(MediaTypes.HAL_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
startsWith("http://localhost/" + AccessContext.tenant() + "/controller/v1/"
|
||||||
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/" + actionId)));
|
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/" + actionId)));
|
||||||
final long timeAfterFirstPoll = System.currentTimeMillis() + 1;
|
final long timeAfterFirstPoll = System.currentTimeMillis() + 1;
|
||||||
assertThat(targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).getLastTargetQuery())
|
assertThat(targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).getLastTargetQuery())
|
||||||
@@ -192,21 +193,21 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
assertThat(activeActionsByTarget.get(0).getStatus()).isEqualTo(Status.CANCELING);
|
assertThat(activeActionsByTarget.get(0).getStatus()).isEqualTo(Status.CANCELING);
|
||||||
|
|
||||||
final long timeBefore2ndPoll = System.currentTimeMillis();
|
final long timeBefore2ndPoll = System.currentTimeMillis();
|
||||||
mvc.perform(get("/{tenant}/controller/v1/{controller}", tenantAware.getCurrentTenant(),
|
mvc.perform(get("/{tenant}/controller/v1/{controller}", AccessContext.tenant(),
|
||||||
TestdataFactory.DEFAULT_CONTROLLER_ID))
|
TestdataFactory.DEFAULT_CONTROLLER_ID))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.cancelAction.href",
|
.andExpect(jsonPath("$._links.cancelAction.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
equalTo("http://localhost/" + AccessContext.tenant() + "/controller/v1/"
|
||||||
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction.getId())));
|
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction.getId())));
|
||||||
final long timeAfter2ndPoll = System.currentTimeMillis() + 1;
|
final long timeAfter2ndPoll = System.currentTimeMillis() + 1;
|
||||||
assertThat(targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).getLastTargetQuery())
|
assertThat(targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).getLastTargetQuery())
|
||||||
.isBetween(timeBefore2ndPoll, timeAfter2ndPoll);
|
.isBetween(timeBefore2ndPoll, timeAfter2ndPoll);
|
||||||
|
|
||||||
mvc.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId(), tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON))
|
+ cancelAction.getId(), AccessContext.tenant()).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||||
@@ -217,7 +218,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// controller confirmed cancelled action, should not be active anymore
|
// controller confirmed cancelled action, should not be active anymore
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON)
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant()).accept(MediaType.APPLICATION_JSON)
|
||||||
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -240,22 +241,22 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// not allowed methods
|
// not allowed methods
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/1",
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/1",
|
||||||
tenantAware.getCurrentTenant()))
|
AccessContext.tenant()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(put("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/1",
|
mvc.perform(put("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/1",
|
||||||
tenantAware.getCurrentTenant()))
|
AccessContext.tenant()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(delete("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/1",
|
mvc.perform(delete("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/1",
|
||||||
tenantAware.getCurrentTenant()))
|
AccessContext.tenant()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
// non existing target
|
// non existing target
|
||||||
mvc.perform(get("/{tenant}/controller/v1/34534543/cancelAction/1", tenantAware.getCurrentTenant())
|
mvc.perform(get("/{tenant}/controller/v1/34534543/cancelAction/1", AccessContext.tenant())
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -263,7 +264,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
createCancelAction("34534543");
|
createCancelAction("34534543");
|
||||||
|
|
||||||
// wrong media type
|
// wrong media type
|
||||||
mvc.perform(get("/{tenant}/controller/v1/34534543/cancelAction/1", tenantAware.getCurrentTenant())
|
mvc.perform(get("/{tenant}/controller/v1/34534543/cancelAction/1", AccessContext.tenant())
|
||||||
.accept(MediaType.APPLICATION_ATOM_XML))
|
.accept(MediaType.APPLICATION_ATOM_XML))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotAcceptable());
|
.andExpect(status().isNotAcceptable());
|
||||||
@@ -289,7 +290,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)).hasSize(1);
|
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)).hasSize(1);
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonProceedingCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonProceedingCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -299,7 +300,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
assertThat(countActionStatusAll()).isEqualTo(3);
|
assertThat(countActionStatusAll()).isEqualTo(3);
|
||||||
|
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonResumedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonResumedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -308,7 +309,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
assertThat(countActionStatusAll()).isEqualTo(4);
|
assertThat(countActionStatusAll()).isEqualTo(4);
|
||||||
|
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonScheduledCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonScheduledCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -319,7 +320,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// cancellation canceled -> should remove the action from active
|
// cancellation canceled -> should remove the action from active
|
||||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)).hasSize(1);
|
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)).hasSize(1);
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonCanceledCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonCanceledCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -333,7 +334,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// error
|
// error
|
||||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)).hasSize(1);
|
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)).hasSize(1);
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonRejectedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonRejectedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -343,7 +344,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// update closed -> should remove the action from active
|
// update closed -> should remove the action from active
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -383,7 +384,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
assertThat(deploymentManagement.countActionsByTarget(savedTarget.getControllerId())).isEqualTo(3);
|
assertThat(deploymentManagement.countActionsByTarget(savedTarget.getControllerId())).isEqualTo(3);
|
||||||
mvc.perform(get(
|
mvc.perform(get(
|
||||||
"/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction.getId(),
|
"/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction.getId(),
|
||||||
tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON))
|
AccessContext.tenant()).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
@@ -391,19 +392,19 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
.andExpect(jsonPath("$.cancelAction.stopId", equalTo(String.valueOf(actionId))));
|
.andExpect(jsonPath("$.cancelAction.stopId", equalTo(String.valueOf(actionId))));
|
||||||
assertThat(countActionStatusAll()).isEqualTo(6);
|
assertThat(countActionStatusAll()).isEqualTo(6);
|
||||||
|
|
||||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}", tenantAware.getCurrentTenant(),
|
mvc.perform(get("/{tenant}/controller/v1/{controllerId}", AccessContext.tenant(),
|
||||||
TestdataFactory.DEFAULT_CONTROLLER_ID))
|
TestdataFactory.DEFAULT_CONTROLLER_ID))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.cancelAction.href",
|
.andExpect(jsonPath("$._links.cancelAction.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
equalTo("http://localhost/" + AccessContext.tenant() + "/controller/v1/"
|
||||||
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction.getId())));
|
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction.getId())));
|
||||||
|
|
||||||
// now lets return feedback for the first cancelation
|
// now lets return feedback for the first cancelation
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -414,7 +415,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)).hasSize(2);
|
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)).hasSize(2);
|
||||||
assertThat(deploymentManagement.countActionsByTarget(savedTarget.getControllerId())).isEqualTo(3);
|
assertThat(deploymentManagement.countActionsByTarget(savedTarget.getControllerId())).isEqualTo(3);
|
||||||
mvc.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction2.getId(), tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON))
|
+ cancelAction2.getId(), AccessContext.tenant()).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||||
@@ -422,19 +423,19 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
.andExpect(jsonPath("$.cancelAction.stopId", equalTo(String.valueOf(actionId2))));
|
.andExpect(jsonPath("$.cancelAction.stopId", equalTo(String.valueOf(actionId2))));
|
||||||
assertThat(countActionStatusAll()).isEqualTo(8);
|
assertThat(countActionStatusAll()).isEqualTo(8);
|
||||||
|
|
||||||
mvc.perform(get("/{tenant}/controller/v1/{controller}", tenantAware.getCurrentTenant(),
|
mvc.perform(get("/{tenant}/controller/v1/{controller}", AccessContext.tenant(),
|
||||||
TestdataFactory.DEFAULT_CONTROLLER_ID))
|
TestdataFactory.DEFAULT_CONTROLLER_ID))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.cancelAction.href",
|
.andExpect(jsonPath("$._links.cancelAction.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
equalTo("http://localhost/" + AccessContext.tenant() + "/controller/v1/"
|
||||||
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction2.getId())));
|
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction2.getId())));
|
||||||
|
|
||||||
// now lets return feedback for the second cancelation
|
// now lets return feedback for the second cancelation
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction2.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction2.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -444,7 +445,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
assertThat(deploymentManagement.findAssignedDistributionSet(TestdataFactory.DEFAULT_CONTROLLER_ID).orElseThrow()).isEqualTo(ds3);
|
assertThat(deploymentManagement.findAssignedDistributionSet(TestdataFactory.DEFAULT_CONTROLLER_ID).orElseThrow()).isEqualTo(ds3);
|
||||||
mvc.perform(
|
mvc.perform(
|
||||||
get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/" + actionId3,
|
get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/" + actionId3,
|
||||||
tenantAware.getCurrentTenant()))
|
AccessContext.tenant()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
assertThat(countActionStatusAll()).isEqualTo(10);
|
assertThat(countActionStatusAll()).isEqualTo(10);
|
||||||
@@ -461,7 +462,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
mvc.perform(get(
|
mvc.perform(get(
|
||||||
"/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction3.getId(),
|
"/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction3.getId(),
|
||||||
tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON))
|
AccessContext.tenant()).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||||
@@ -471,7 +472,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// now lets return feedback for the third cancelation
|
// now lets return feedback for the third cancelation
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction3.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction3.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -502,13 +503,13 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// only 97 action status left
|
// only 97 action status left
|
||||||
for (int i = 0; i < 98; i++) {
|
for (int i = 0; i < 98; i++) {
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant()).content(feedback)
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant()).content(feedback)
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
|
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant()).content(feedback)
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant()).content(feedback)
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isTooManyRequests());
|
.andExpect(status().isTooManyRequests());
|
||||||
}
|
}
|
||||||
@@ -523,25 +524,25 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// not allowed methods
|
// not allowed methods
|
||||||
mvc.perform(put("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(put("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(delete("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(delete("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant()))
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant()))
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
// bad content type
|
// bad content type
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_ATOM_XML)
|
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_ATOM_XML)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -550,14 +551,14 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// bad body
|
// bad body
|
||||||
String invalidFeedback = "{\"status\":{\"execution\":\"546456456\",\"result\":{\"finished\":\"none\",\"progress\":{\"cnt\":2,\"of\":5}},\"details\":\"none\"]}}";
|
String invalidFeedback = "{\"status\":{\"execution\":\"546456456\",\"result\":{\"finished\":\"none\",\"progress\":{\"cnt\":2,\"of\":5}},\"details\":\"none\"]}}";
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant()).content(invalidFeedback)
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant()).content(invalidFeedback)
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
|
|
||||||
// non existing target
|
// non existing target
|
||||||
mvc.perform(post("/{tenant}/controller/v1/12345/cancelAction/" + cancelAction.getId() + "/feedback",
|
mvc.perform(post("/{tenant}/controller/v1/12345/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||||
tenantAware.getCurrentTenant()).content(getJsonClosedCancelActionFeedback())
|
AccessContext.tenant()).content(getJsonClosedCancelActionFeedback())
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -565,14 +566,14 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// invalid action
|
// invalid action
|
||||||
invalidFeedback = "{\"id\":\"sdfsdfsdfs\",\"status\":{\"execution\":\"closed\",\"result\":{\"finished\":\"none\",\"progress\":{\"cnt\":2,\"of\":5}},\"details\":\"details\"]}}";
|
invalidFeedback = "{\"id\":\"sdfsdfsdfs\",\"status\":{\"execution\":\"closed\",\"result\":{\"finished\":\"none\",\"progress\":{\"cnt\":2,\"of\":5}},\"details\":\"details\"]}}";
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant()).content(invalidFeedback)
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant()).content(invalidFeedback)
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
|
|
||||||
// finaly, get it right :)
|
// finaly, get it right :)
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", AccessContext.tenant())
|
||||||
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
.content(getJsonClosedCancelActionFeedback()).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
||||||
@@ -62,7 +63,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final Map<String, String> attributes = new HashMap<>();
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
attributes.put(ATTRIBUTE_KEY_VALID, ATTRIBUTE_VALUE_VALID);
|
attributes.put(ATTRIBUTE_KEY_VALID, ATTRIBUTE_VALUE_VALID);
|
||||||
|
|
||||||
mvc.perform(put(TARGET1_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(TARGET1_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(jsonToCbor(JsonBuilder.configData(attributes).toString()))
|
.content(jsonToCbor(JsonBuilder.configData(attributes).toString()))
|
||||||
.contentType(DdiRestConstants.MEDIA_TYPE_CBOR))
|
.contentType(DdiRestConstants.MEDIA_TYPE_CBOR))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -80,13 +81,13 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final Target savedTarget = testdataFactory.createTarget("4712");
|
final Target savedTarget = testdataFactory.createTarget("4712");
|
||||||
|
|
||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant()).accept(MediaTypes.HAL_JSON))
|
mvc.perform(get("/{tenant}/controller/v1/4712", AccessContext.tenant()).accept(MediaTypes.HAL_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.configData.href", equalTo(
|
.andExpect(jsonPath("$._links.configData.href", equalTo(
|
||||||
"http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/4712/configData")));
|
"http://localhost/" + AccessContext.tenant() + "/controller/v1/4712/configData")));
|
||||||
Thread.sleep(1); // is required: otherwise processing the next line is
|
Thread.sleep(1); // is required: otherwise processing the next line is
|
||||||
// often too fast and // the following assert will fail
|
// often too fast and // the following assert will fail
|
||||||
assertThat(targetManagement.getByControllerId("4712")
|
assertThat(targetManagement.getByControllerId("4712")
|
||||||
@@ -102,7 +103,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// to request the controller attributes again
|
// to request the controller attributes again
|
||||||
assertThat(updateControllerAttributes.isRequestControllerAttributes()).isFalse();
|
assertThat(updateControllerAttributes.isRequestControllerAttributes()).isFalse();
|
||||||
|
|
||||||
mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant()).accept(MediaTypes.HAL_JSON))
|
mvc.perform(get("/{tenant}/controller/v1/4712", AccessContext.tenant()).accept(MediaTypes.HAL_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
@@ -122,7 +123,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final Map<String, String> attributes = new HashMap<>();
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
attributes.put(ATTRIBUTE_KEY_VALID, ATTRIBUTE_VALUE_VALID);
|
attributes.put(ATTRIBUTE_KEY_VALID, ATTRIBUTE_VALUE_VALID);
|
||||||
|
|
||||||
mvc.perform(put(TARGET1_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(TARGET1_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
@@ -130,7 +131,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// update
|
// update
|
||||||
attributes.put("sdsds", "123412");
|
attributes.put("sdsds", "123412");
|
||||||
mvc.perform(put(TARGET1_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(TARGET1_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
@@ -150,12 +151,12 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
for (int i = 0; i < quotaManagement.getMaxAttributeEntriesPerTarget(); i++) {
|
for (int i = 0; i < quotaManagement.getMaxAttributeEntriesPerTarget(); i++) {
|
||||||
attributes.put("dsafsdf" + i, "sdsds" + i);
|
attributes.put("dsafsdf" + i, "sdsds" + i);
|
||||||
}
|
}
|
||||||
mvc.perform(put(TARGET1_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(TARGET1_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString())
|
.content(JsonBuilder.configData(attributes).toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
mvc.perform(put(TARGET1_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(TARGET1_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(Map.of("on too many", "sdsds")).toString())
|
.content(JsonBuilder.configData(Map.of("on too many", "sdsds")).toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isTooManyRequests())
|
.andExpect(status().isTooManyRequests())
|
||||||
@@ -172,33 +173,33 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
testdataFactory.createTarget("4712");
|
testdataFactory.createTarget("4712");
|
||||||
|
|
||||||
// not allowed methods
|
// not allowed methods
|
||||||
mvc.perform(post("/{tenant}/controller/v1/4712/configData", tenantAware.getCurrentTenant()))
|
mvc.perform(post("/{tenant}/controller/v1/4712/configData", AccessContext.tenant()))
|
||||||
.andDo(MockMvcResultPrinter.print()).//
|
.andDo(MockMvcResultPrinter.print()).//
|
||||||
andExpect(status().isMethodNotAllowed());
|
andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(get("/{tenant}/controller/v1/4712/configData", tenantAware.getCurrentTenant()))
|
mvc.perform(get("/{tenant}/controller/v1/4712/configData", AccessContext.tenant()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(delete("/{tenant}/controller/v1/4712/configData", tenantAware.getCurrentTenant()))
|
mvc.perform(delete("/{tenant}/controller/v1/4712/configData", AccessContext.tenant()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
// bad content type
|
// bad content type
|
||||||
final Map<String, String> attributes = Map.of("dsafsdf", "sdsds");
|
final Map<String, String> attributes = Map.of("dsafsdf", "sdsds");
|
||||||
mvc.perform(put("/{tenant}/controller/v1/4712/configData", tenantAware.getCurrentTenant())
|
mvc.perform(put("/{tenant}/controller/v1/4712/configData", AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaTypes.HAL_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaTypes.HAL_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isUnsupportedMediaType());
|
.andExpect(status().isUnsupportedMediaType());
|
||||||
|
|
||||||
// non existing target
|
// non existing target
|
||||||
mvc.perform(put("/{tenant}/controller/v1/456456/configData", tenantAware.getCurrentTenant())
|
mvc.perform(put("/{tenant}/controller/v1/456456/configData", AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
|
|
||||||
// bad body
|
// bad body
|
||||||
mvc.perform(put("/{tenant}/controller/v1/4712/configData", tenantAware.getCurrentTenant())
|
mvc.perform(put("/{tenant}/controller/v1/4712/configData", AccessContext.tenant())
|
||||||
.content("{\"id\": \"51659181\"}").contentType(MediaType.APPLICATION_JSON))
|
.content("{\"id\": \"51659181\"}").contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
@@ -241,7 +242,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
private void putAndVerifyConfigDataWithKeyTooLong() throws Exception {
|
private void putAndVerifyConfigDataWithKeyTooLong() throws Exception {
|
||||||
final Map<String, String> attributes = Collections.singletonMap(ATTRIBUTE_KEY_TOO_LONG, ATTRIBUTE_VALUE_VALID);
|
final Map<String, String> attributes = Collections.singletonMap(ATTRIBUTE_KEY_TOO_LONG, ATTRIBUTE_VALUE_VALID);
|
||||||
mvc.perform(put(DdiConfigDataTest.TARGET2_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET2_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isBadRequest())
|
.andExpect(status().isBadRequest())
|
||||||
.andExpect(jsonPath("$.exceptionClass", equalTo(InvalidTargetAttributeException.class.getName())))
|
.andExpect(jsonPath("$.exceptionClass", equalTo(InvalidTargetAttributeException.class.getName())))
|
||||||
@@ -250,7 +251,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
private void putAndVerifyConfigDataWithValueTooLong() throws Exception {
|
private void putAndVerifyConfigDataWithValueTooLong() throws Exception {
|
||||||
final Map<String, String> attributes = Collections.singletonMap(ATTRIBUTE_KEY_VALID, ATTRIBUTE_VALUE_TOO_LONG);
|
final Map<String, String> attributes = Collections.singletonMap(ATTRIBUTE_KEY_VALID, ATTRIBUTE_VALUE_TOO_LONG);
|
||||||
mvc.perform(put(DdiConfigDataTest.TARGET2_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET2_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isBadRequest())
|
.andExpect(status().isBadRequest())
|
||||||
.andExpect(jsonPath("$.exceptionClass", equalTo(InvalidTargetAttributeException.class.getName())))
|
.andExpect(jsonPath("$.exceptionClass", equalTo(InvalidTargetAttributeException.class.getName())))
|
||||||
@@ -264,7 +265,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
"k1", "v1");
|
"k1", "v1");
|
||||||
|
|
||||||
// use an invalid update mode
|
// use an invalid update mode
|
||||||
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(attributes, "KJHGKJHGKJHG").toString())
|
.content(JsonBuilder.configData(attributes, "KJHGKJHGKJHG").toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -280,7 +281,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
"k1", "foo",
|
"k1", "foo",
|
||||||
"k3", "bar");
|
"k3", "bar");
|
||||||
|
|
||||||
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(removeAttributes, "remove").toString())
|
.content(JsonBuilder.configData(removeAttributes, "remove").toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -302,7 +303,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final Map<String, String> mergeAttributes = Map.of(
|
final Map<String, String> mergeAttributes = Map.of(
|
||||||
"k1", "v1_modified_again",
|
"k1", "v1_modified_again",
|
||||||
"k4", "v4");
|
"k4", "v4");
|
||||||
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(mergeAttributes, "merge").toString())
|
.content(JsonBuilder.configData(mergeAttributes, "merge").toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -325,7 +326,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
"k1", "v1_modified",
|
"k1", "v1_modified",
|
||||||
"k2", "v2",
|
"k2", "v2",
|
||||||
"k3", "v3");
|
"k3", "v3");
|
||||||
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(replacementAttributes, "replace").toString())
|
.content(JsonBuilder.configData(replacementAttributes, "replace").toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -346,7 +347,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
"k1", "v1");
|
"k1", "v1");
|
||||||
|
|
||||||
// set the initial attributes
|
// set the initial attributes
|
||||||
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIG_DATA_PATH, AccessContext.tenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiActivateAutoConfirmation;
|
import org.eclipse.hawkbit.ddi.json.model.DdiActivateAutoConfirmation;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiConfirmationFeedback;
|
import org.eclipse.hawkbit.ddi.json.model.DdiConfirmationFeedback;
|
||||||
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
||||||
@@ -106,9 +107,9 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
final String expectedConfirmationBaseLink = String.format(
|
final String expectedConfirmationBaseLink = String.format(
|
||||||
"/%s/controller/v1/%s/confirmationBase/%d",
|
"/%s/controller/v1/%s/confirmationBase/%d",
|
||||||
tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, uaction.getId());
|
AccessContext.tenant(), DEFAULT_CONTROLLER_ID, uaction.getId());
|
||||||
|
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID)
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(), DEFAULT_CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.confirmationBase.href", containsString(expectedConfirmationBaseLink)))
|
.andExpect(jsonPath("$._links.confirmationBase.href", containsString(expectedConfirmationBaseLink)))
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist());
|
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist());
|
||||||
@@ -150,11 +151,11 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// get confirmation base
|
// get confirmation base
|
||||||
performGet(CONFIRMATION_BASE_ACTION, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR),
|
performGet(CONFIRMATION_BASE_ACTION, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR),
|
||||||
status().isOk(), tenantAware.getCurrentTenant(), target.getControllerId(), action.getId().toString());
|
status().isOk(), AccessContext.tenant(), target.getControllerId(), action.getId().toString());
|
||||||
|
|
||||||
// get artifacts
|
// get artifacts
|
||||||
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR),
|
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR),
|
||||||
status().isOk(), tenantAware.getCurrentTenant(), target.getControllerId(),
|
status().isOk(), AccessContext.tenant(), target.getControllerId(),
|
||||||
String.valueOf(softwareModuleId));
|
String.valueOf(softwareModuleId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,12 +171,12 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final String controllerId = savedTarget.getControllerId();
|
final String controllerId = savedTarget.getControllerId();
|
||||||
final Action savedAction = deploymentManagement.findActiveActionsByTarget(controllerId, PAGE).getContent().get(0);
|
final Action savedAction = deploymentManagement.findActiveActionsByTarget(controllerId, PAGE).getContent().get(0);
|
||||||
|
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._links.confirmationBase.href").doesNotExist());
|
.andExpect(jsonPath("$._links.confirmationBase.href").doesNotExist());
|
||||||
|
|
||||||
mvc.perform(get(CONFIRMATION_BASE_ACTION, tenantAware.getCurrentTenant(), controllerId, savedAction.getId())
|
mvc.perform(get(CONFIRMATION_BASE_ACTION, AccessContext.tenant(), controllerId, savedAction.getId())
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -195,18 +196,18 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final String controllerId = savedTarget.getControllerId();
|
final String controllerId = savedTarget.getControllerId();
|
||||||
|
|
||||||
final Action savedAction = deploymentManagement.findActiveActionsByTarget(controllerId, PAGE).getContent().get(0);
|
final Action savedAction = deploymentManagement.findActiveActionsByTarget(controllerId, PAGE).getContent().get(0);
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._links.confirmationBase.href").exists())
|
.andExpect(jsonPath("$._links.confirmationBase.href").exists())
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist());
|
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist());
|
||||||
|
|
||||||
mvc.perform(get(CONFIRMATION_BASE_ACTION, tenantAware.getCurrentTenant(), controllerId, savedAction.getId())
|
mvc.perform(get(CONFIRMATION_BASE_ACTION, AccessContext.tenant(), controllerId, savedAction.getId())
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
mvc.perform(get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), controllerId, savedAction.getId())
|
mvc.perform(get(DEPLOYMENT_BASE, AccessContext.tenant(), controllerId, savedAction.getId())
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -300,13 +301,13 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
final String confirmationBaseActionLink = String.format(
|
final String confirmationBaseActionLink = String.format(
|
||||||
"/%s/controller/v1/%s/confirmationBase/%d",
|
"/%s/controller/v1/%s/confirmationBase/%d",
|
||||||
tenantAware.getCurrentTenant(), controllerId, actionId);
|
AccessContext.tenant(), controllerId, actionId);
|
||||||
|
|
||||||
final String activateAutoConfLink = String.format(
|
final String activateAutoConfLink = String.format(
|
||||||
"/%s/controller/v1/%s/confirmationBase/activateAutoConfirm",
|
"/%s/controller/v1/%s/confirmationBase/activateAutoConfirm",
|
||||||
tenantAware.getCurrentTenant(), controllerId);
|
AccessContext.tenant(), controllerId);
|
||||||
|
|
||||||
mvc.perform(get(CONFIRMATION_BASE, tenantAware.getCurrentTenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(CONFIRMATION_BASE, AccessContext.tenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("autoConfirm.active", equalTo(Boolean.FALSE)))
|
.andExpect(jsonPath("autoConfirm.active", equalTo(Boolean.FALSE)))
|
||||||
@@ -327,9 +328,9 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
final String deactivateAutoConfLink = String.format(
|
final String deactivateAutoConfLink = String.format(
|
||||||
"/%s/controller/v1/%s/confirmationBase/deactivateAutoConfirm",
|
"/%s/controller/v1/%s/confirmationBase/deactivateAutoConfirm",
|
||||||
tenantAware.getCurrentTenant(), controllerId);
|
AccessContext.tenant(), controllerId);
|
||||||
|
|
||||||
mvc.perform(get(CONFIRMATION_BASE, tenantAware.getCurrentTenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(CONFIRMATION_BASE, AccessContext.tenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("autoConfirm.active", equalTo(Boolean.TRUE)))
|
.andExpect(jsonPath("autoConfirm.active", equalTo(Boolean.TRUE)))
|
||||||
@@ -353,7 +354,7 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
final DdiActivateAutoConfirmation body = new DdiActivateAutoConfirmation(initiator, remark);
|
final DdiActivateAutoConfirmation body = new DdiActivateAutoConfirmation(initiator, remark);
|
||||||
|
|
||||||
mvc.perform(post(ACTIVATE_AUTO_CONFIRM, tenantAware.getCurrentTenant(), controllerId)
|
mvc.perform(post(ACTIVATE_AUTO_CONFIRM, AccessContext.tenant(), controllerId)
|
||||||
.content(getMapper().writeValueAsString(body)).contentType(MediaType.APPLICATION_JSON))
|
.content(getMapper().writeValueAsString(body)).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
@@ -374,7 +375,7 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
confirmationManagement.activateAutoConfirmation(controllerId, null, null);
|
confirmationManagement.activateAutoConfirmation(controllerId, null, null);
|
||||||
|
|
||||||
mvc.perform(post(DEACTIVATE_AUTO_CONFIRM, tenantAware.getCurrentTenant(), controllerId))
|
mvc.perform(post(DEACTIVATE_AUTO_CONFIRM, AccessContext.tenant(), controllerId))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
@@ -414,15 +415,15 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// asserts that deployment link is not available
|
// asserts that deployment link is not available
|
||||||
final String expectedConfirmationBaseLink = String.format(
|
final String expectedConfirmationBaseLink = String.format(
|
||||||
"/%s/controller/v1/%s/confirmationBase/%d",
|
"/%s/controller/v1/%s/confirmationBase/%d",
|
||||||
tenantAware.getCurrentTenant(), controllerId, savedAction.getId());
|
AccessContext.tenant(), controllerId, savedAction.getId());
|
||||||
|
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist())
|
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist())
|
||||||
.andExpect(jsonPath("$._links.confirmationBase.href", containsString(expectedConfirmationBaseLink)));
|
.andExpect(jsonPath("$._links.confirmationBase.href", containsString(expectedConfirmationBaseLink)));
|
||||||
|
|
||||||
mvc.perform(get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), controllerId, savedAction.getId())
|
mvc.perform(get(DEPLOYMENT_BASE, AccessContext.tenant(), controllerId, savedAction.getId())
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -460,14 +461,14 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
// confirmationBase not available in RUNNING state anymore
|
// confirmationBase not available in RUNNING state anymore
|
||||||
mvc.perform(get(CONFIRMATION_BASE_ACTION, tenantAware.getCurrentTenant(), savedTarget.getControllerId(),
|
mvc.perform(get(CONFIRMATION_BASE_ACTION, AccessContext.tenant(), savedTarget.getControllerId(),
|
||||||
savedAction.getId()).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
savedAction.getId()).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
|
|
||||||
// assert confirmed message against deploymentBase endpoint
|
// assert confirmed message against deploymentBase endpoint
|
||||||
// this call will update the action due to retrieved action status update
|
// this call will update the action due to retrieved action status update
|
||||||
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory=2", tenantAware.getCurrentTenant(), savedTarget.getControllerId(),
|
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory=2", AccessContext.tenant(), savedTarget.getControllerId(),
|
||||||
savedAction.getId()).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
savedAction.getId()).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -487,9 +488,9 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
private void verifyActionInDeploymentBaseState(final String controllerId, final long actionId) throws Exception {
|
private void verifyActionInDeploymentBaseState(final String controllerId, final long actionId) throws Exception {
|
||||||
final String expectedDeploymentBaseLink = String.format(
|
final String expectedDeploymentBaseLink = String.format(
|
||||||
"/%s/controller/v1/%s/deploymentBase/%d",
|
"/%s/controller/v1/%s/deploymentBase/%d",
|
||||||
tenantAware.getCurrentTenant(), controllerId, actionId);
|
AccessContext.tenant(), controllerId, actionId);
|
||||||
|
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href", containsString(expectedDeploymentBaseLink)))
|
.andExpect(jsonPath("$._links.deploymentBase.href", containsString(expectedDeploymentBaseLink)))
|
||||||
@@ -502,18 +503,18 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void verifyActionInConfirmationBaseState(final String controllerId, final long actionId) throws Exception {
|
private void verifyActionInConfirmationBaseState(final String controllerId, final long actionId) throws Exception {
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._links.confirmationBase.href").exists())
|
.andExpect(jsonPath("$._links.confirmationBase.href").exists())
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist());
|
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist());
|
||||||
|
|
||||||
mvc.perform(get(CONFIRMATION_BASE_ACTION, tenantAware.getCurrentTenant(), controllerId, actionId)
|
mvc.perform(get(CONFIRMATION_BASE_ACTION, AccessContext.tenant(), controllerId, actionId)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
mvc.perform(get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), controllerId, actionId)
|
mvc.perform(get(DEPLOYMENT_BASE, AccessContext.tenant(), controllerId, actionId)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -528,7 +529,7 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
final String feedback = getJsonConfirmationFeedback(confirmation, code, Collections.singletonList(message));
|
final String feedback = getJsonConfirmationFeedback(confirmation, code, Collections.singletonList(message));
|
||||||
return mvc.perform(
|
return mvc.perform(
|
||||||
post(CONFIRMATION_FEEDBACK, tenantAware.getCurrentTenant(), target.getControllerId(), action.getId())
|
post(CONFIRMATION_FEEDBACK, AccessContext.tenant(), target.getControllerId(), action.getId())
|
||||||
.content(feedback).contentType(MediaType.APPLICATION_JSON));
|
.content(feedback).contentType(MediaType.APPLICATION_JSON));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import com.jayway.jsonpath.JsonPath;
|
import com.jayway.jsonpath.JsonPath;
|
||||||
import org.assertj.core.api.Condition;
|
import org.assertj.core.api.Condition;
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
|
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
|
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
|
||||||
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
||||||
@@ -96,11 +97,11 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// get deployment base
|
// get deployment base
|
||||||
performGet(DEPLOYMENT_BASE, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR), status().isOk(),
|
performGet(DEPLOYMENT_BASE, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR), status().isOk(),
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), action.getId().toString());
|
AccessContext.tenant(), target.getControllerId(), action.getId().toString());
|
||||||
|
|
||||||
// get artifacts
|
// get artifacts
|
||||||
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR),
|
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR),
|
||||||
status().isOk(), tenantAware.getCurrentTenant(), target.getControllerId(),
|
status().isOk(), AccessContext.tenant(), target.getControllerId(),
|
||||||
String.valueOf(softwareModuleId));
|
String.valueOf(softwareModuleId));
|
||||||
|
|
||||||
final byte[] feedback = jsonToCbor(getJsonProceedingDeploymentActionFeedback());
|
final byte[] feedback = jsonToCbor(getJsonProceedingDeploymentActionFeedback());
|
||||||
@@ -115,7 +116,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
void artifactsNotFound() throws Exception {
|
void artifactsNotFound() throws Exception {
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.APPLICATION_JSON, status().isNotFound(), tenantAware.getCurrentTenant(),
|
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.APPLICATION_JSON, status().isNotFound(), AccessContext.tenant(),
|
||||||
target.getControllerId(), "1");
|
target.getControllerId(), "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +133,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
assignDistributionSet(distributionSet.getId(), target.getName());
|
assignDistributionSet(distributionSet.getId(), target.getName());
|
||||||
|
|
||||||
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.APPLICATION_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.APPLICATION_JSON, status().isOk(), AccessContext.tenant(),
|
||||||
target.getControllerId(), softwareModuleId.toString())
|
target.getControllerId(), softwareModuleId.toString())
|
||||||
.andExpect(jsonPath("$", hasSize(3)))
|
.andExpect(jsonPath("$", hasSize(3)))
|
||||||
.andExpect(jsonPath("$.[?(@.filename=='filename0')]", hasSize(1)))
|
.andExpect(jsonPath("$.[?(@.filename=='filename0')]", hasSize(1)))
|
||||||
@@ -174,7 +175,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// Run test
|
// Run test
|
||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(),
|
||||||
DEFAULT_CONTROLLER_ID)
|
DEFAULT_CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath(
|
.andExpect(jsonPath(
|
||||||
@@ -209,14 +210,14 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
ActionType.TIMEFORCED, System.currentTimeMillis() + 2_000));
|
ActionType.TIMEFORCED, System.currentTimeMillis() + 2_000));
|
||||||
|
|
||||||
MvcResult mvcResult = performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(),
|
MvcResult mvcResult = performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(),
|
||||||
tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID)
|
AccessContext.tenant(), DEFAULT_CONTROLLER_ID)
|
||||||
.andReturn();
|
.andReturn();
|
||||||
|
|
||||||
final String urlBeforeSwitch = JsonPath.compile("_links.deploymentBase.href")
|
final String urlBeforeSwitch = JsonPath.compile("_links.deploymentBase.href")
|
||||||
.read(mvcResult.getResponse().getContentAsString()).toString();
|
.read(mvcResult.getResponse().getContentAsString()).toString();
|
||||||
|
|
||||||
// Time is not yet over, so we should see the same URL
|
// Time is not yet over, so we should see the same URL
|
||||||
mvcResult = performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
mvcResult = performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(),
|
||||||
DEFAULT_CONTROLLER_ID)
|
DEFAULT_CONTROLLER_ID)
|
||||||
.andReturn();
|
.andReturn();
|
||||||
assertThat(JsonPath.compile("_links.deploymentBase.href").read(mvcResult.getResponse().getContentAsString())
|
assertThat(JsonPath.compile("_links.deploymentBase.href").read(mvcResult.getResponse().getContentAsString())
|
||||||
@@ -226,7 +227,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// After the time is over we should see a new etag
|
// After the time is over we should see a new etag
|
||||||
TimeUnit.MILLISECONDS.sleep(2_000);
|
TimeUnit.MILLISECONDS.sleep(2_000);
|
||||||
|
|
||||||
mvcResult = performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
mvcResult = performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(),
|
||||||
DEFAULT_CONTROLLER_ID)
|
DEFAULT_CONTROLLER_ID)
|
||||||
.andReturn();
|
.andReturn();
|
||||||
|
|
||||||
@@ -272,7 +273,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// Run test
|
// Run test
|
||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(),
|
||||||
DEFAULT_CONTROLLER_ID)
|
DEFAULT_CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||||
@@ -326,7 +327,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// Run test
|
// Run test
|
||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(),
|
||||||
DEFAULT_CONTROLLER_ID)
|
DEFAULT_CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||||
@@ -388,7 +389,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// Run test
|
// Run test
|
||||||
|
|
||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID)
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(), DEFAULT_CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||||
startsWith(deploymentBaseLink(DEFAULT_CONTROLLER_ID, uaction.getId().toString()))));
|
startsWith(deploymentBaseLink(DEFAULT_CONTROLLER_ID, uaction.getId().toString()))));
|
||||||
@@ -416,25 +417,25 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final Target target = testdataFactory.createTarget(DEFAULT_CONTROLLER_ID);
|
final Target target = testdataFactory.createTarget(DEFAULT_CONTROLLER_ID);
|
||||||
|
|
||||||
// not allowed methods
|
// not allowed methods
|
||||||
mvc.perform(post(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "1"))
|
mvc.perform(post(DEPLOYMENT_BASE, AccessContext.tenant(), DEFAULT_CONTROLLER_ID, "1"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(put(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "1"))
|
mvc.perform(put(DEPLOYMENT_BASE, AccessContext.tenant(), DEFAULT_CONTROLLER_ID, "1"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(delete(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "1"))
|
mvc.perform(delete(DEPLOYMENT_BASE, AccessContext.tenant(), DEFAULT_CONTROLLER_ID, "1"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
// non existing target
|
// non existing target
|
||||||
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), "not-existing", "1"))
|
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE, AccessContext.tenant(), "not-existing", "1"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
|
|
||||||
// no deployment
|
// no deployment
|
||||||
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "1"))
|
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE, AccessContext.tenant(), DEFAULT_CONTROLLER_ID, "1"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
|
|
||||||
@@ -443,12 +444,12 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final DistributionSet savedSet = testdataFactory.createDistributionSet("");
|
final DistributionSet savedSet = testdataFactory.createDistributionSet("");
|
||||||
|
|
||||||
final Long actionId = getFirstAssignedActionId(assignDistributionSet(savedSet, toAssign));
|
final Long actionId = getFirstAssignedActionId(assignDistributionSet(savedSet, toAssign));
|
||||||
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID,
|
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE, AccessContext.tenant(), DEFAULT_CONTROLLER_ID,
|
||||||
actionId))
|
actionId))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
mvc.perform(MockMvcRequestBuilders
|
mvc.perform(MockMvcRequestBuilders
|
||||||
.get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, actionId)
|
.get(DEPLOYMENT_BASE, AccessContext.tenant(), DEFAULT_CONTROLLER_ID, actionId)
|
||||||
.accept(MediaType.APPLICATION_ATOM_XML))
|
.accept(MediaType.APPLICATION_ATOM_XML))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotAcceptable());
|
.andExpect(status().isNotAcceptable());
|
||||||
@@ -643,16 +644,16 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
DdiResult.FinalResult.NONE, Collections.singletonList("")), status().isNotFound());
|
DdiResult.FinalResult.NONE, Collections.singletonList("")), status().isNotFound());
|
||||||
|
|
||||||
// not allowed methods
|
// not allowed methods
|
||||||
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_FEEDBACK, tenantAware.getCurrentTenant(),
|
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_FEEDBACK, AccessContext.tenant(),
|
||||||
DEFAULT_CONTROLLER_ID, "2"))
|
DEFAULT_CONTROLLER_ID, "2"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(put(DEPLOYMENT_FEEDBACK, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "2"))
|
mvc.perform(put(DEPLOYMENT_FEEDBACK, AccessContext.tenant(), DEFAULT_CONTROLLER_ID, "2"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(delete(DEPLOYMENT_FEEDBACK, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "2"))
|
mvc.perform(delete(DEPLOYMENT_FEEDBACK, AccessContext.tenant(), DEFAULT_CONTROLLER_ID, "2"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
|
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
|
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
|
||||||
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
||||||
@@ -90,11 +91,11 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// get installed base
|
// get installed base
|
||||||
performGet(INSTALLED_BASE, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR), status().isOk(),
|
performGet(INSTALLED_BASE, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR), status().isOk(),
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), actionId.toString());
|
AccessContext.tenant(), target.getControllerId(), actionId.toString());
|
||||||
|
|
||||||
// get artifacts
|
// get artifacts
|
||||||
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR),
|
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR),
|
||||||
status().isOk(), tenantAware.getCurrentTenant(), target.getControllerId(),
|
status().isOk(), AccessContext.tenant(), target.getControllerId(),
|
||||||
String.valueOf(softwareModuleId));
|
String.valueOf(softwareModuleId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +154,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// Run test with 1st action
|
// Run test with 1st action
|
||||||
final Long actionId1 = getFirstAssignedActionId(
|
final Long actionId1 = getFirstAssignedActionId(
|
||||||
assignDistributionSet(ds1.getId(), target.getControllerId(), Action.ActionType.SOFT));
|
assignDistributionSet(ds1.getId(), target.getControllerId(), Action.ActionType.SOFT));
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), CONTROLLER_ID)
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(), CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist())
|
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist())
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||||
@@ -172,7 +173,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// Run test with 2nd action
|
// Run test with 2nd action
|
||||||
final Long actionId2 = getFirstAssignedActionId(
|
final Long actionId2 = getFirstAssignedActionId(
|
||||||
assignDistributionSet(ds2.getId(), target.getControllerId(), Action.ActionType.FORCED));
|
assignDistributionSet(ds2.getId(), target.getControllerId(), Action.ActionType.FORCED));
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), CONTROLLER_ID)
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(), CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.installedBase.href",
|
.andExpect(jsonPath("$._links.installedBase.href",
|
||||||
startsWith(installedBaseLink(CONTROLLER_ID, actionId1.toString()))))
|
startsWith(installedBaseLink(CONTROLLER_ID, actionId1.toString()))))
|
||||||
@@ -189,7 +190,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
getAndVerifyInstalledBasePayload(CONTROLLER_ID, MediaType.APPLICATION_JSON, ds2, artifact2, artifactSignature2,
|
getAndVerifyInstalledBasePayload(CONTROLLER_ID, MediaType.APPLICATION_JSON, ds2, artifact2, artifactSignature2,
|
||||||
actionId2, findFirstModuleByType(ds2, osType).orElseThrow().getId(), Action.ActionType.FORCED);
|
actionId2, findFirstModuleByType(ds2, osType).orElseThrow().getId(), Action.ActionType.FORCED);
|
||||||
|
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), CONTROLLER_ID)
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(), CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.installedBase.href",
|
.andExpect(jsonPath("$._links.installedBase.href",
|
||||||
startsWith(installedBaseLink(CONTROLLER_ID, actionId2.toString()))))
|
startsWith(installedBaseLink(CONTROLLER_ID, actionId2.toString()))))
|
||||||
@@ -238,7 +239,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
status().isOk());
|
status().isOk());
|
||||||
|
|
||||||
// Test: latest succeeded action is returned in installedBase
|
// Test: latest succeeded action is returned in installedBase
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), CONTROLLER_ID)
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(), CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.installedBase.href",
|
.andExpect(jsonPath("$._links.installedBase.href",
|
||||||
startsWith(installedBaseLink(CONTROLLER_ID, actionId3.toString()))))
|
startsWith(installedBaseLink(CONTROLLER_ID, actionId3.toString()))))
|
||||||
@@ -248,11 +249,11 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
actionId3, findFirstModuleByType(ds1, osType).orElseThrow().getId(), Action.ActionType.SOFT);
|
actionId3, findFirstModuleByType(ds1, osType).orElseThrow().getId(), Action.ActionType.SOFT);
|
||||||
|
|
||||||
// cancelled action are not accessible
|
// cancelled action are not accessible
|
||||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), target.getControllerId(),
|
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, AccessContext.tenant(), target.getControllerId(),
|
||||||
actionId1.toString()))
|
actionId1.toString()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), target.getControllerId(),
|
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, AccessContext.tenant(), target.getControllerId(),
|
||||||
actionId2.toString()))
|
actionId2.toString()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -297,7 +298,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// Test: the succeeded action is returned in installedBase instead of the latest
|
// Test: the succeeded action is returned in installedBase instead of the latest
|
||||||
// cancelled action
|
// cancelled action
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), CONTROLLER_ID)
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(), CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.installedBase.href",
|
.andExpect(jsonPath("$._links.installedBase.href",
|
||||||
startsWith(installedBaseLink(CONTROLLER_ID, actionId1.toString()))))
|
startsWith(installedBaseLink(CONTROLLER_ID, actionId1.toString()))))
|
||||||
@@ -307,11 +308,11 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
actionId1, findFirstModuleByType(ds1, osType).orElseThrow().getId(), Action.ActionType.SOFT);
|
actionId1, findFirstModuleByType(ds1, osType).orElseThrow().getId(), Action.ActionType.SOFT);
|
||||||
|
|
||||||
// cancelled action are not accessible
|
// cancelled action are not accessible
|
||||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), target.getControllerId(),
|
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, AccessContext.tenant(), target.getControllerId(),
|
||||||
actionId2.toString()))
|
actionId2.toString()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), target.getControllerId(),
|
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, AccessContext.tenant(), target.getControllerId(),
|
||||||
actionId3.toString()))
|
actionId3.toString()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -351,7 +352,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
status().isOk());
|
status().isOk());
|
||||||
|
|
||||||
// Test: the succeeded action is returned in installedBase instead of the latest cancelled action
|
// Test: the succeeded action is returned in installedBase instead of the latest cancelled action
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), CONTROLLER_ID)
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(), CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.installedBase.href",
|
.andExpect(jsonPath("$._links.installedBase.href",
|
||||||
startsWith(installedBaseLink(CONTROLLER_ID, actionId1.toString()))))
|
startsWith(installedBaseLink(CONTROLLER_ID, actionId1.toString()))))
|
||||||
@@ -362,11 +363,11 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
actionId1, findFirstModuleByType(ds1, osType).orElseThrow().getId(), Action.ActionType.SOFT);
|
actionId1, findFirstModuleByType(ds1, osType).orElseThrow().getId(), Action.ActionType.SOFT);
|
||||||
|
|
||||||
// cancelled action are not accessible
|
// cancelled action are not accessible
|
||||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), target.getControllerId(),
|
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, AccessContext.tenant(), target.getControllerId(),
|
||||||
actionId2.toString()))
|
actionId2.toString()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), target.getControllerId(),
|
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, AccessContext.tenant(), target.getControllerId(),
|
||||||
actionId3.toString()))
|
actionId3.toString()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -382,16 +383,16 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
final Long actionId = getFirstAssignedActionId(assignDistributionSet(ds, target));
|
final Long actionId = getFirstAssignedActionId(assignDistributionSet(ds, target));
|
||||||
|
|
||||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), CONTROLLER_ID)
|
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), AccessContext.tenant(), CONTROLLER_ID)
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist())
|
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist())
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||||
startsWith(deploymentBaseLink(CONTROLLER_ID, actionId.toString()))));
|
startsWith(deploymentBaseLink(CONTROLLER_ID, actionId.toString()))));
|
||||||
|
|
||||||
performGet(DEPLOYMENT_BASE, MediaType.APPLICATION_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
performGet(DEPLOYMENT_BASE, MediaType.APPLICATION_JSON, status().isOk(), AccessContext.tenant(),
|
||||||
target.getControllerId(), actionId.toString());
|
target.getControllerId(), actionId.toString());
|
||||||
|
|
||||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), target.getControllerId(),
|
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, AccessContext.tenant(), target.getControllerId(),
|
||||||
actionId.toString()))
|
actionId.toString()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -413,7 +414,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
postDeploymentFeedback(target.getControllerId(), actionId, getJsonClosedDeploymentActionFeedback(), status().isOk());
|
postDeploymentFeedback(target.getControllerId(), actionId, getJsonClosedDeploymentActionFeedback(), status().isOk());
|
||||||
|
|
||||||
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.APPLICATION_JSON, status().isOk(),
|
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.APPLICATION_JSON, status().isOk(),
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), softwareModuleId.toString())
|
AccessContext.tenant(), target.getControllerId(), softwareModuleId.toString())
|
||||||
.andExpect(jsonPath("$", hasSize(3)))
|
.andExpect(jsonPath("$", hasSize(3)))
|
||||||
.andExpect(jsonPath("$.[?(@.filename=='filename0')]", hasSize(1)))
|
.andExpect(jsonPath("$.[?(@.filename=='filename0')]", hasSize(1)))
|
||||||
.andExpect(jsonPath("$.[?(@.filename=='filename1')]", hasSize(1)))
|
.andExpect(jsonPath("$.[?(@.filename=='filename1')]", hasSize(1)))
|
||||||
@@ -454,13 +455,13 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// Run test
|
// Run test
|
||||||
final ResultActions resultActions = performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(),
|
final ResultActions resultActions = performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(),
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId());
|
AccessContext.tenant(), target.getControllerId());
|
||||||
resultActions.andDo(MockMvcResultPrinter.print())
|
resultActions.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist())
|
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist())
|
||||||
.andExpect(jsonPath("$._links.installedBase.href", containsString(String.format(
|
.andExpect(jsonPath("$._links.installedBase.href", containsString(String.format(
|
||||||
"/%s/controller/v1/%s/installedBase/%d",
|
"/%s/controller/v1/%s/installedBase/%d",
|
||||||
tenantAware.getCurrentTenant(), target.getControllerId(), actionId))));
|
AccessContext.tenant(), target.getControllerId(), actionId))));
|
||||||
|
|
||||||
getAndVerifyInstalledBasePayload(CONTROLLER_ID, MediaType.APPLICATION_JSON, ds, artifact, artifactSignature,
|
getAndVerifyInstalledBasePayload(CONTROLLER_ID, MediaType.APPLICATION_JSON, ds, artifact, artifactSignature,
|
||||||
actionId, findFirstModuleByType(ds, osType).orElseThrow().getId(), actionType);
|
actionId, findFirstModuleByType(ds, osType).orElseThrow().getId(), actionType);
|
||||||
@@ -499,7 +500,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final Long actionId = getFirstAssignedActionId(
|
final Long actionId = getFirstAssignedActionId(
|
||||||
assignDistributionSet(ds.getId(), target.getControllerId(), Action.ActionType.DOWNLOAD_ONLY));
|
assignDistributionSet(ds.getId(), target.getControllerId(), Action.ActionType.DOWNLOAD_ONLY));
|
||||||
|
|
||||||
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), AccessContext.tenant(),
|
||||||
target.getControllerId())
|
target.getControllerId())
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -510,7 +511,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
postDeploymentFeedback(target.getControllerId(), actionId, getJsonDownloadedDeploymentActionFeedback(), status().isOk());
|
postDeploymentFeedback(target.getControllerId(), actionId, getJsonDownloadedDeploymentActionFeedback(), status().isOk());
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), AccessContext.tenant(),
|
||||||
target.getControllerId())
|
target.getControllerId())
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -530,7 +531,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final Long actionId = getFirstAssignedActionId(
|
final Long actionId = getFirstAssignedActionId(
|
||||||
assignDistributionSet(ds.getId(), target.getControllerId(), actionType));
|
assignDistributionSet(ds.getId(), target.getControllerId(), actionType));
|
||||||
|
|
||||||
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), AccessContext.tenant(),
|
||||||
target.getControllerId())
|
target.getControllerId())
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -546,7 +547,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
status().isOk());
|
status().isOk());
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), AccessContext.tenant(),
|
||||||
target.getControllerId())
|
target.getControllerId())
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -581,14 +582,14 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
// Test
|
// Test
|
||||||
// for zero input no action history is returned
|
// for zero input no action history is returned
|
||||||
mvc.perform(get(INSTALLED_BASE + "?actionHistory", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
mvc.perform(get(INSTALLED_BASE + "?actionHistory", AccessContext.tenant(), 911, savedAction.getId())
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.actionHistory.messages").doesNotExist());
|
.andExpect(jsonPath("$.actionHistory.messages").doesNotExist());
|
||||||
|
|
||||||
// depending on given query parameter value, only the latest messages are returned
|
// depending on given query parameter value, only the latest messages are returned
|
||||||
mvc.perform(get(INSTALLED_BASE + "?actionHistory=2", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
mvc.perform(get(INSTALLED_BASE + "?actionHistory=2", AccessContext.tenant(), 911, savedAction.getId())
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -598,7 +599,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
jsonPath("$.actionHistory.messages", not(hasItem(containsString("Installation scheduled")))));
|
jsonPath("$.actionHistory.messages", not(hasItem(containsString("Installation scheduled")))));
|
||||||
|
|
||||||
// for negative input the entire action history is returned
|
// for negative input the entire action history is returned
|
||||||
mvc.perform(get(INSTALLED_BASE + "?actionHistory=-3", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
mvc.perform(get(INSTALLED_BASE + "?actionHistory=-3", AccessContext.tenant(), 911, savedAction.getId())
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -615,25 +616,25 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final Target target = testdataFactory.createTarget(CONTROLLER_ID);
|
final Target target = testdataFactory.createTarget(CONTROLLER_ID);
|
||||||
|
|
||||||
// not allowed methods
|
// not allowed methods
|
||||||
mvc.perform(post(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, "1"))
|
mvc.perform(post(INSTALLED_BASE, AccessContext.tenant(), CONTROLLER_ID, "1"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(put(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, "1"))
|
mvc.perform(put(INSTALLED_BASE, AccessContext.tenant(), CONTROLLER_ID, "1"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
mvc.perform(delete(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, "1"))
|
mvc.perform(delete(INSTALLED_BASE, AccessContext.tenant(), CONTROLLER_ID, "1"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isMethodNotAllowed());
|
.andExpect(status().isMethodNotAllowed());
|
||||||
|
|
||||||
// non existing target
|
// non existing target
|
||||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), "not-existing", "1"))
|
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, AccessContext.tenant(), "not-existing", "1"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
|
|
||||||
// no deployment
|
// no deployment
|
||||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, "1"))
|
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, AccessContext.tenant(), CONTROLLER_ID, "1"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
|
|
||||||
@@ -643,10 +644,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
final Long actionId = getFirstAssignedActionId(assignDistributionSet(savedSet, toAssign));
|
final Long actionId = getFirstAssignedActionId(assignDistributionSet(savedSet, toAssign));
|
||||||
postDeploymentFeedback(CONTROLLER_ID, actionId, getJsonClosedCancelActionFeedback(), status().isOk());
|
postDeploymentFeedback(CONTROLLER_ID, actionId, getJsonClosedCancelActionFeedback(), status().isOk());
|
||||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, actionId))
|
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, AccessContext.tenant(), CONTROLLER_ID, actionId))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, actionId)
|
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, AccessContext.tenant(), CONTROLLER_ID, actionId)
|
||||||
.accept(MediaType.APPLICATION_ATOM_XML))
|
.accept(MediaType.APPLICATION_ATOM_XML))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotAcceptable());
|
.andExpect(status().isNotAcceptable());
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
package org.eclipse.hawkbit.ddi.rest.resource;
|
package org.eclipse.hawkbit.ddi.rest.resource;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.eclipse.hawkbit.im.authentication.SpPermission.TENANT_CONFIGURATION;
|
import static org.eclipse.hawkbit.auth.SpPermission.TENANT_CONFIGURATION;
|
||||||
import static org.eclipse.hawkbit.im.authentication.SpRole.CONTROLLER_ROLE_ANONYMOUS;
|
import static org.eclipse.hawkbit.auth.SpRole.CONTROLLER_ROLE_ANONYMOUS;
|
||||||
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.callAs;
|
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.callAs;
|
||||||
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.getAs;
|
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.getAs;
|
||||||
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.withController;
|
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.withController;
|
||||||
@@ -37,10 +37,11 @@ import java.util.Map;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.auth.SpPermission;
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
|
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
|
||||||
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
|
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
|
||||||
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
|
||||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||||
@@ -65,7 +66,7 @@ import org.eclipse.hawkbit.repository.test.util.WithUser;
|
|||||||
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
|
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
|
||||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.utils.IpUtil;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.hateoas.MediaTypes;
|
import org.springframework.hateoas.MediaTypes;
|
||||||
@@ -93,7 +94,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void rootPollResourceCbor() throws Exception {
|
void rootPollResourceCbor() throws Exception {
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711).accept(DdiRestConstants.MEDIA_TYPE_CBOR))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), 4711).accept(DdiRestConstants.MEDIA_TYPE_CBOR))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(content().contentType(DdiRestConstants.MEDIA_TYPE_CBOR))
|
.andExpect(content().contentType(DdiRestConstants.MEDIA_TYPE_CBOR))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
@@ -104,7 +105,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void apiReturnsJSONByDefault() throws Exception {
|
void apiReturnsJSONByDefault() throws Exception {
|
||||||
final MvcResult result = mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711))
|
final MvcResult result = mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), 4711))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
@@ -132,7 +133,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// make a poll, audit information should not be changed, run as controller principal!
|
// make a poll, audit information should not be changed, run as controller principal!
|
||||||
callAs(withController("controller", CONTROLLER_ROLE_ANONYMOUS),
|
callAs(withController("controller", CONTROLLER_ROLE_ANONYMOUS),
|
||||||
() -> {
|
() -> {
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), knownTargetControllerId))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), knownTargetControllerId))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
return null;
|
return null;
|
||||||
@@ -205,7 +206,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
withPollingTime("00:02:00", () -> callAs(
|
withPollingTime("00:02:00", () -> callAs(
|
||||||
withUser("controller", CONTROLLER_ROLE_ANONYMOUS),
|
withUser("controller", CONTROLLER_ROLE_ANONYMOUS),
|
||||||
() -> {
|
() -> {
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), 4711))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
@@ -226,7 +227,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1),
|
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TenantConfigurationDeletedEvent.class, count = 1) })
|
@Expect(type = TenantConfigurationDeletedEvent.class, count = 1) })
|
||||||
void pollWithModifiedWithOverridesGlobalPollingTime() throws Exception {
|
void pollWithModifiedWithOverridesGlobalPollingTime() throws Exception {
|
||||||
SecurityContextSwitch.callAsPrivileged(() -> {
|
SecurityContextSwitch.asPrivileged(() -> {
|
||||||
final Target target = testdataFactory.createTarget("not4711");
|
final Target target = testdataFactory.createTarget("not4711");
|
||||||
targetManagement.assignTargetsWithGroup("Europe", List.of(target.getControllerId()));
|
targetManagement.assignTargetsWithGroup("Europe", List.of(target.getControllerId()));
|
||||||
return null;
|
return null;
|
||||||
@@ -235,13 +236,13 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
withPollingTime("00:02:00, controllerid == 4711 -> 00:01:00, group == 'Europe' -> 00:05:05", () -> callAs(
|
withPollingTime("00:02:00, controllerid == 4711 -> 00:01:00, group == 'Europe' -> 00:05:05", () -> callAs(
|
||||||
withUser("controller", CONTROLLER_ROLE_ANONYMOUS),
|
withUser("controller", CONTROLLER_ROLE_ANONYMOUS),
|
||||||
() -> {
|
() -> {
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), 4711))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")));
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")));
|
||||||
|
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), "not4711"))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), "not4711"))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
@@ -268,7 +269,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1) })
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1) })
|
||||||
void rootRsNotModified() throws Exception {
|
void rootRsNotModified() throws Exception {
|
||||||
final String controllerId = "4711";
|
final String controllerId = "4711";
|
||||||
final String etag = mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId))
|
final String etag = mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
@@ -276,7 +277,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||||
.andReturn().getResponse()
|
.andReturn().getResponse()
|
||||||
.getHeader("ETag");
|
.getHeader("ETag");
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).header("If-None-Match", etag))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId).header("If-None-Match", etag))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotModified());
|
.andExpect(status().isNotModified());
|
||||||
|
|
||||||
@@ -286,7 +287,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
final Action updateAction = deploymentManagement.findActiveActionsByTarget(target.getControllerId(), PAGE).getContent().get(0);
|
final Action updateAction = deploymentManagement.findActiveActionsByTarget(target.getControllerId(), PAGE).getContent().get(0);
|
||||||
final String etagWithFirstUpdate = mvc
|
final String etagWithFirstUpdate = mvc
|
||||||
.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId)
|
.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId)
|
||||||
.header("If-None-Match", etag)
|
.header("If-None-Match", etag)
|
||||||
.accept(MediaType.APPLICATION_JSON)
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
.with(new RequestOnHawkbitDefaultPortPostProcessor()))
|
.with(new RequestOnHawkbitDefaultPortPostProcessor()))
|
||||||
@@ -299,7 +300,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
startsWith(deploymentBaseLink("4711", updateAction.getId().toString()))))
|
startsWith(deploymentBaseLink("4711", updateAction.getId().toString()))))
|
||||||
.andReturn().getResponse().getHeader("ETag");
|
.andReturn().getResponse().getHeader("ETag");
|
||||||
assertThat(etagWithFirstUpdate).isNotNull();
|
assertThat(etagWithFirstUpdate).isNotNull();
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).header("If-None-Match",
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId).header("If-None-Match",
|
||||||
etagWithFirstUpdate).with(new RequestOnHawkbitDefaultPortPostProcessor()))
|
etagWithFirstUpdate).with(new RequestOnHawkbitDefaultPortPostProcessor()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotModified());
|
.andExpect(status().isNotModified());
|
||||||
@@ -311,7 +312,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// as the update was installed, and we always receive the installed action, the
|
// as the update was installed, and we always receive the installed action, the
|
||||||
// original state cannot be restored
|
// original state cannot be restored
|
||||||
final String etagAfterInstallation = mvc
|
final String etagAfterInstallation = mvc
|
||||||
.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId)
|
.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId)
|
||||||
.header("If-None-Match", etag).accept(MediaType.APPLICATION_JSON)
|
.header("If-None-Match", etag).accept(MediaType.APPLICATION_JSON)
|
||||||
.with(new RequestOnHawkbitDefaultPortPostProcessor()))
|
.with(new RequestOnHawkbitDefaultPortPostProcessor()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -327,7 +328,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final DistributionSet ds2 = testdataFactory.createDistributionSet("2");
|
final DistributionSet ds2 = testdataFactory.createDistributionSet("2");
|
||||||
assignDistributionSet(ds2.getId(), controllerId);
|
assignDistributionSet(ds2.getId(), controllerId);
|
||||||
final Action updateAction2 = deploymentManagement.findActiveActionsByTarget(target.getControllerId(), PAGE).getContent().get(0);
|
final Action updateAction2 = deploymentManagement.findActiveActionsByTarget(target.getControllerId(), PAGE).getContent().get(0);
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId)
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId)
|
||||||
.header("If-None-Match", etagAfterInstallation).accept(MediaType.APPLICATION_JSON)
|
.header("If-None-Match", etagAfterInstallation).accept(MediaType.APPLICATION_JSON)
|
||||||
.with(new RequestOnHawkbitDefaultPortPostProcessor()))
|
.with(new RequestOnHawkbitDefaultPortPostProcessor()))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
@@ -355,7 +356,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
testdataFactory.createTarget(controllerId);
|
testdataFactory.createTarget(controllerId);
|
||||||
assertThat(targetManagement.getByControllerId(controllerId).getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
|
assertThat(targetManagement.getByControllerId(controllerId).getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
@@ -382,7 +383,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// make a poll, audit information should be set on plug and play
|
// make a poll, audit information should be set on plug and play
|
||||||
callAs(withController("controller", CONTROLLER_ROLE_ANONYMOUS),
|
callAs(withController("controller", CONTROLLER_ROLE_ANONYMOUS),
|
||||||
() -> {
|
() -> {
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), knownControllerId1))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), knownControllerId1))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
return null;
|
return null;
|
||||||
@@ -408,7 +409,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
securityProperties.getClients().setTrackRemoteIp(false);
|
securityProperties.getClients().setTrackRemoteIp(false);
|
||||||
// test
|
// test
|
||||||
final String knownControllerId1 = "0815";
|
final String knownControllerId1 = "0815";
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), knownControllerId1))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), knownControllerId1))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
// verify
|
// verify
|
||||||
@@ -468,7 +469,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
final Target savedTarget = testdataFactory.createTarget("922");
|
final Target savedTarget = testdataFactory.createTarget("922");
|
||||||
final Map<String, String> attributes = Collections.singletonMap("AttributeKey", "AttributeValue");
|
final Map<String, String> attributes = Collections.singletonMap("AttributeKey", "AttributeValue");
|
||||||
assertThatAttributesUpdateIsRequested(savedTarget.getControllerId());
|
assertThatAttributesUpdateIsRequested(savedTarget.getControllerId());
|
||||||
mvc.perform(put(CONTROLLER_BASE + "/configData", tenantAware.getCurrentTenant(), savedTarget.getControllerId())
|
mvc.perform(put(CONTROLLER_BASE + "/configData", AccessContext.tenant(), savedTarget.getControllerId())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
assertThatAttributesUpdateIsNotRequested(savedTarget.getControllerId());
|
assertThatAttributesUpdateIsNotRequested(savedTarget.getControllerId());
|
||||||
@@ -505,7 +506,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
sendDeploymentActionFeedback(savedTarget, savedAction, "closed", "success", TARGET_COMPLETED_INSTALLATION_MSG)
|
sendDeploymentActionFeedback(savedTarget, savedAction, "closed", "success", TARGET_COMPLETED_INSTALLATION_MSG)
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory=2", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory=2", AccessContext.tenant(), 911, savedAction.getId())
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -543,12 +544,12 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
sendDeploymentActionFeedback(savedTarget, savedAction, "closed", "success", TARGET_COMPLETED_INSTALLATION_MSG)
|
sendDeploymentActionFeedback(savedTarget, savedAction, "closed", "success", TARGET_COMPLETED_INSTALLATION_MSG)
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory=0", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory=0", AccessContext.tenant(), 911, savedAction.getId())
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.actionHistory.messages").doesNotExist());
|
.andExpect(jsonPath("$.actionHistory.messages").doesNotExist());
|
||||||
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory", AccessContext.tenant(), 911, savedAction.getId())
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -584,7 +585,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
sendDeploymentActionFeedback(savedTarget, savedAction, "closed", "success", TARGET_COMPLETED_INSTALLATION_MSG)
|
sendDeploymentActionFeedback(savedTarget, savedAction, "closed", "success", TARGET_COMPLETED_INSTALLATION_MSG)
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory=-1", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory=-1", AccessContext.tenant(), 911, savedAction.getId())
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -602,7 +603,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
getAs(withUser("tenantadmin", TENANT_CONFIGURATION),
|
getAs(withUser("tenantadmin", TENANT_CONFIGURATION),
|
||||||
() -> {
|
() -> {
|
||||||
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME, "00:05:00");
|
tenantConfigurationManagement().addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME, "00:05:00");
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -657,7 +658,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
mvc.perform(get(CONTROLLER_BASE, "default-tenant", "1911")).andExpect(status().isOk());
|
mvc.perform(get(CONTROLLER_BASE, "default-tenant", "1911")).andExpect(status().isOk());
|
||||||
|
|
||||||
final Action action = deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE).getContent().get(0);
|
final Action action = deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE).getContent().get(0);
|
||||||
mvc.perform(get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), "1911", action.getId()).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(DEPLOYMENT_BASE, AccessContext.tenant(), "1911", action.getId()).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.deployment.download", equalTo("forced")))
|
.andExpect(jsonPath("$.deployment.download", equalTo("forced")))
|
||||||
@@ -678,7 +679,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
mvc.perform(get(CONTROLLER_BASE, "default-tenant", "1911")).andExpect(status().isOk());
|
mvc.perform(get(CONTROLLER_BASE, "default-tenant", "1911")).andExpect(status().isOk());
|
||||||
|
|
||||||
final Action action = deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE).getContent().get(0);
|
final Action action = deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE).getContent().get(0);
|
||||||
mvc.perform(get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), "1911", action.getId()).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(DEPLOYMENT_BASE, AccessContext.tenant(), "1911", action.getId()).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.deployment.download", equalTo("forced")))
|
.andExpect(jsonPath("$.deployment.download", equalTo("forced")))
|
||||||
@@ -709,7 +710,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
void rootRsWithInvalidControllerId() throws Exception {
|
void rootRsWithInvalidControllerId() throws Exception {
|
||||||
final String invalidControllerId = randomString(Target.CONTROLLER_ID_MAX_SIZE + 1);
|
final String invalidControllerId = randomString(Target.CONTROLLER_ID_MAX_SIZE + 1);
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), invalidControllerId)).andExpect(status().isBadRequest());
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), invalidControllerId)).andExpect(status().isBadRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertAttributesUpdateNotRequestedAfterFailedDeployment(Target target, final DistributionSet ds) throws Exception {
|
private void assertAttributesUpdateNotRequestedAfterFailedDeployment(Target target, final DistributionSet ds) throws Exception {
|
||||||
@@ -727,13 +728,13 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatAttributesUpdateIsRequested(final String targetControllerId) throws Exception {
|
private void assertThatAttributesUpdateIsRequested(final String targetControllerId) throws Exception {
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), targetControllerId).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), targetControllerId).accept(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._links.configData.href").isNotEmpty());
|
.andExpect(jsonPath("$._links.configData.href").isNotEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatAttributesUpdateIsNotRequested(final String targetControllerId) throws Exception {
|
private void assertThatAttributesUpdateIsNotRequested(final String targetControllerId) throws Exception {
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), targetControllerId).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), targetControllerId).accept(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._links.configData").doesNotExist());
|
.andExpect(jsonPath("$._links.configData").doesNotExist());
|
||||||
}
|
}
|
||||||
@@ -749,7 +750,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
final String feedback = getJsonActionFeedback(DdiStatus.ExecutionStatus.valueOf(execution.toUpperCase()),
|
final String feedback = getJsonActionFeedback(DdiStatus.ExecutionStatus.valueOf(execution.toUpperCase()),
|
||||||
DdiResult.FinalResult.valueOf(finished.toUpperCase()), Collections.singletonList(message));
|
DdiResult.FinalResult.valueOf(finished.toUpperCase()), Collections.singletonList(message));
|
||||||
return mvc.perform(post(DEPLOYMENT_FEEDBACK, tenantAware.getCurrentTenant(), target.getControllerId(), action.getId())
|
return mvc.perform(post(DEPLOYMENT_FEEDBACK, AccessContext.tenant(), target.getControllerId(), action.getId())
|
||||||
.content(feedback).contentType(MediaType.APPLICATION_JSON));
|
.content(feedback).contentType(MediaType.APPLICATION_JSON));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -761,8 +762,8 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
private void assertDeploymentActionIsExposedToTarget(final String controllerId, final long expectedActionId) throws Exception {
|
private void assertDeploymentActionIsExposedToTarget(final String controllerId, final long expectedActionId) throws Exception {
|
||||||
final String expectedDeploymentBaseLink = String.format(
|
final String expectedDeploymentBaseLink = String.format(
|
||||||
"/%s/controller/v1/%s/deploymentBase/%d",
|
"/%s/controller/v1/%s/deploymentBase/%d",
|
||||||
tenantAware.getCurrentTenant(), controllerId, expectedActionId);
|
AccessContext.tenant(), controllerId, expectedActionId);
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._links.deploymentBase.href", containsString(expectedDeploymentBaseLink)));
|
.andExpect(jsonPath("$._links.deploymentBase.href", containsString(expectedDeploymentBaseLink)));
|
||||||
@@ -771,7 +772,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
private void withPollingTime(final String pollingTime, final Callable<Void> runnable) throws Exception {
|
private void withPollingTime(final String pollingTime, final Callable<Void> runnable) throws Exception {
|
||||||
getAs(withUser("tenantadmin", TENANT_CONFIGURATION),
|
getAs(withUser("tenantadmin", TENANT_CONFIGURATION),
|
||||||
() -> {
|
() -> {
|
||||||
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME, pollingTime);
|
tenantConfigurationManagement().addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME, pollingTime);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
@@ -779,7 +780,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
} finally {
|
} finally {
|
||||||
getAs(withUser("tenantadmin", TENANT_CONFIGURATION),
|
getAs(withUser("tenantadmin", TENANT_CONFIGURATION),
|
||||||
() -> {
|
() -> {
|
||||||
tenantConfigurationManagement.deleteConfiguration(TenantConfigurationKey.POLLING_TIME);
|
tenantConfigurationManagement().deleteConfiguration(TenantConfigurationKey.POLLING_TIME);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
@@ -53,7 +54,7 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void blackListedClientIsForbidden() throws Exception {
|
void blackListedClientIsForbidden() throws Exception {
|
||||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
mvc.perform(get("/{tenant}/controller/v1/4711", AccessContext.tenant())
|
||||||
.header(X_FORWARDED_FOR, "192.168.0.4 , 10.0.0.1 "))
|
.header(X_FORWARDED_FOR, "192.168.0.4 , 10.0.0.1 "))
|
||||||
.andExpect(status().isForbidden());
|
.andExpect(status().isForbidden());
|
||||||
}
|
}
|
||||||
@@ -66,7 +67,7 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
int requests = 0;
|
int requests = 0;
|
||||||
MvcResult result;
|
MvcResult result;
|
||||||
do {
|
do {
|
||||||
result = mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
result = mvc.perform(get("/{tenant}/controller/v1/4711", AccessContext.tenant())
|
||||||
.header(X_FORWARDED_FOR, "10.0.0.1"))
|
.header(X_FORWARDED_FOR, "10.0.0.1"))
|
||||||
.andReturn();
|
.andReturn();
|
||||||
requests++;
|
requests++;
|
||||||
@@ -85,7 +86,7 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
void unacceptableGetLoadButOnWhitelistIPv4() throws Exception {
|
void unacceptableGetLoadButOnWhitelistIPv4() throws Exception {
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
mvc.perform(get("/{tenant}/controller/v1/4711", AccessContext.tenant())
|
||||||
.header(X_FORWARDED_FOR, "127.0.0.1"))
|
.header(X_FORWARDED_FOR, "127.0.0.1"))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
@@ -97,7 +98,7 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
void unacceptableGetLoadButOnWhitelistIPv6() throws Exception {
|
void unacceptableGetLoadButOnWhitelistIPv6() throws Exception {
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
mvc.perform(get("/{tenant}/controller/v1/4711", AccessContext.tenant())
|
||||||
.header(X_FORWARDED_FOR, "0:0:0:0:0:0:0:1"))
|
.header(X_FORWARDED_FOR, "0:0:0:0:0:0:0:1"))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
@@ -114,7 +115,7 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
// sleep for one second
|
// sleep for one second
|
||||||
Thread.sleep(1100);
|
Thread.sleep(1100);
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
mvc.perform(get("/{tenant}/controller/v1/4711", AccessContext.tenant())
|
||||||
.header(X_FORWARDED_FOR, "10.0.0.1"))
|
.header(X_FORWARDED_FOR, "10.0.0.1"))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
@@ -133,7 +134,7 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
MvcResult result;
|
MvcResult result;
|
||||||
do {
|
do {
|
||||||
result = mvc.perform(post("/{tenant}/controller/v1/4711/deploymentBase/" + actionId + "/feedback",
|
result = mvc.perform(post("/{tenant}/controller/v1/4711/deploymentBase/" + actionId + "/feedback",
|
||||||
tenantAware.getCurrentTenant()).header(X_FORWARDED_FOR, "10.0.0.1").content(feedback)
|
AccessContext.tenant()).header(X_FORWARDED_FOR, "10.0.0.1").content(feedback)
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andReturn();
|
.andReturn();
|
||||||
requests++;
|
requests++;
|
||||||
@@ -162,7 +163,7 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
mvc.perform(post("/{tenant}/controller/v1/4711/deploymentBase/" + actionId + "/feedback",
|
mvc.perform(post("/{tenant}/controller/v1/4711/deploymentBase/" + actionId + "/feedback",
|
||||||
tenantAware.getCurrentTenant()).header(X_FORWARDED_FOR, "10.0.0.1")
|
AccessContext.tenant()).header(X_FORWARDED_FOR, "10.0.0.1")
|
||||||
.content(feedback).contentType(MediaType.APPLICATION_JSON)
|
.content(feedback).contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|||||||
@@ -9,24 +9,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ddi.rest.resource;
|
package org.eclipse.hawkbit.ddi.rest.resource;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
|
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
|
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder class for building certain json strings.
|
* Builder class for building certain json strings.
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
package org.eclipse.hawkbit.security.controller;
|
package org.eclipse.hawkbit.security.controller;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -21,14 +22,13 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
|
||||||
import org.eclipse.hawkbit.util.UrlUtils;
|
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||||
import org.springframework.util.AntPathMatcher;
|
import org.springframework.util.AntPathMatcher;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
import org.springframework.web.util.UriUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstraction for all controller based security to parse the e.g. the tenant name from the URL and the controller ID from the URL to do
|
* An abstraction for all controller based security to parse the e.g. the tenant name from the URL and the controller ID from the URL to do
|
||||||
@@ -119,8 +119,9 @@ public class AuthenticationFilters {
|
|||||||
authenticator.log().debug("retrieving principal from URI request {}", requestURI);
|
authenticator.log().debug("retrieving principal from URI request {}", requestURI);
|
||||||
final Map<String, String> extractUriTemplateVariables = pathExtractor
|
final Map<String, String> extractUriTemplateVariables = pathExtractor
|
||||||
.extractUriTemplateVariables(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI);
|
.extractUriTemplateVariables(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI);
|
||||||
final String controllerId = UrlUtils.decodeUriValue(extractUriTemplateVariables.get(CONTROLLER_ID_PLACE_HOLDER));
|
final String controllerId = UriUtils.decode(extractUriTemplateVariables.get(CONTROLLER_ID_PLACE_HOLDER),
|
||||||
final String tenant = UrlUtils.decodeUriValue(extractUriTemplateVariables.get(TENANT_PLACE_HOLDER));
|
StandardCharsets.UTF_8);
|
||||||
|
final String tenant = UriUtils.decode(extractUriTemplateVariables.get(TENANT_PLACE_HOLDER), StandardCharsets.UTF_8);
|
||||||
authenticator.log().trace("Parsed tenant {} and controllerId {} from path request {}", tenant, controllerId, requestURI);
|
authenticator.log().trace("Parsed tenant {} and controllerId {} from path request {}", tenant, controllerId, requestURI);
|
||||||
return createTenantSecurityTokenVariables(request, tenant, controllerId);
|
return createTenantSecurityTokenVariables(request, tenant, controllerId);
|
||||||
} else {
|
} else {
|
||||||
@@ -147,8 +148,8 @@ public class AuthenticationFilters {
|
|||||||
// source ip matches the given pattern -> authenticated
|
// source ip matches the given pattern -> authenticated
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
authenticator.log().debug(
|
authenticator.log().debug("The remote source IP address {} is not in the list of trusted IP addresses {}",
|
||||||
"The remote source IP address {} is not in the list of trusted IP addresses {}", remoteAddress, authorizedSourceIps);
|
remoteAddress, authorizedSourceIps);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,16 +9,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security.controller;
|
package org.eclipse.hawkbit.security.controller;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.context.AccessContext.asSystemAsTenant;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpRole;
|
import org.eclipse.hawkbit.auth.SpRole;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||||
@@ -32,10 +31,10 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|||||||
public interface Authenticator {
|
public interface Authenticator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the authentication mechanism is not enabled for the tenant - it just returns null.
|
* If the auth mechanism is not enabled for the tenant - it just returns null.
|
||||||
* If the authentication mechanism is supported, the filter extracts from the security token the related credentials,
|
* If the auth mechanism is supported, the filter extracts from the security token the related credentials,
|
||||||
* validate them (do authenticate the caller).
|
* validate them (do authenticate the caller).
|
||||||
* If validation / authentication is successful returns an authenticated authentication object. Otherwise,
|
* If validation / auth is successful returns an authenticated auth object. Otherwise,
|
||||||
* throws BadCredentialsException.
|
* throws BadCredentialsException.
|
||||||
*
|
*
|
||||||
* @param controllerSecurityToken the securityToken
|
* @param controllerSecurityToken the securityToken
|
||||||
@@ -47,23 +46,10 @@ public interface Authenticator {
|
|||||||
|
|
||||||
abstract class AbstractAuthenticator implements Authenticator {
|
abstract class AbstractAuthenticator implements Authenticator {
|
||||||
|
|
||||||
protected final TenantConfigurationManagement tenantConfigurationManagement;
|
|
||||||
protected final TenantAware tenantAware;
|
|
||||||
protected final SystemSecurityContext systemSecurityContext;
|
|
||||||
private final Callable<Boolean> isEnabledGetter;
|
|
||||||
|
|
||||||
protected AbstractAuthenticator(
|
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement,
|
|
||||||
final TenantAware tenantAware, final SystemSecurityContext systemSecurityContext) {
|
|
||||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
|
||||||
this.tenantAware = tenantAware;
|
|
||||||
this.systemSecurityContext = systemSecurityContext;
|
|
||||||
isEnabledGetter = () -> systemSecurityContext.runAsSystem(
|
|
||||||
() -> tenantConfigurationManagement.getConfigurationValue(getTenantConfigurationKey(), Boolean.class).getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isEnabled(final ControllerSecurityToken securityToken) {
|
protected boolean isEnabled(final ControllerSecurityToken securityToken) {
|
||||||
return tenantAware.runAsTenant(securityToken.getTenant(), isEnabledGetter);
|
return asSystemAsTenant(
|
||||||
|
securityToken.getTenant(),
|
||||||
|
() -> TenantConfigHelper.getAsSystem(getTenantConfigurationKey(), Boolean.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract String getTenantConfigurationKey();
|
protected abstract String getTenantConfigurationKey();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.security.controller;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ public class DdiSecurityProperties {
|
|||||||
private String sslIssuerHashHeader = "X-Ssl-Issuer-Hash-%d";
|
private String sslIssuerHashHeader = "X-Ssl-Issuer-Hash-%d";
|
||||||
/**
|
/**
|
||||||
* List of trusted (reverse proxy) IP addresses for performing DDI
|
* List of trusted (reverse proxy) IP addresses for performing DDI
|
||||||
* client certificate authentication.
|
* client certificate auth.
|
||||||
*/
|
*/
|
||||||
private List<String> trustedIPs;
|
private List<String> trustedIPs;
|
||||||
}
|
}
|
||||||
@@ -71,25 +71,25 @@ public class DdiSecurityProperties {
|
|||||||
private final Gatewaytoken gatewaytoken = new Gatewaytoken();
|
private final Gatewaytoken gatewaytoken = new Gatewaytoken();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Target token authentication. Tokens are defined per target.
|
* Target token auth. Tokens are defined per target.
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public static class Targettoken {
|
public static class Targettoken {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to true to enable target token authentication.
|
* Set to true to enable target token auth.
|
||||||
*/
|
*/
|
||||||
private boolean enabled = false;
|
private boolean enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gateway token authentication. Tokens are defined per tenant. Use with care!
|
* Gateway token auth. Tokens are defined per tenant. Use with care!
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public static class Gatewaytoken {
|
public static class Gatewaytoken {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gateway token based authentication enabled.
|
* Gateway token based auth enabled.
|
||||||
*/
|
*/
|
||||||
private boolean enabled = false;
|
private boolean enabled = false;
|
||||||
|
|
||||||
@@ -9,16 +9,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security.controller;
|
package org.eclipse.hawkbit.security.controller;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.context.AccessContext.asSystemAsTenant;
|
||||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED;
|
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED;
|
||||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY;
|
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
@@ -35,22 +31,6 @@ public class GatewayTokenAuthenticator extends Authenticator.AbstractAuthenticat
|
|||||||
public static final String GATEWAY_SECURITY_TOKEN_AUTH_SCHEME = "GatewayToken ";
|
public static final String GATEWAY_SECURITY_TOKEN_AUTH_SCHEME = "GatewayToken ";
|
||||||
private static final int OFFSET_GATEWAY_TOKEN = GATEWAY_SECURITY_TOKEN_AUTH_SCHEME.length();
|
private static final int OFFSET_GATEWAY_TOKEN = GATEWAY_SECURITY_TOKEN_AUTH_SCHEME.length();
|
||||||
|
|
||||||
private final Callable<String> gatewaySecurityTokenKeyGetter;
|
|
||||||
|
|
||||||
public GatewayTokenAuthenticator(
|
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
|
|
||||||
final SystemSecurityContext systemSecurityContext) {
|
|
||||||
super(tenantConfigurationManagement, tenantAware, systemSecurityContext);
|
|
||||||
gatewaySecurityTokenKeyGetter = () -> {
|
|
||||||
log.trace("retrieving configuration value for configuration key {}", AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY);
|
|
||||||
|
|
||||||
return systemSecurityContext
|
|
||||||
.runAsSystem(() -> tenantConfigurationManagement
|
|
||||||
.getConfigurationValue(AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class)
|
|
||||||
.getValue());
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Authentication authenticate(final ControllerSecurityToken controllerSecurityToken) {
|
public Authentication authenticate(final ControllerSecurityToken controllerSecurityToken) {
|
||||||
final String authHeader = controllerSecurityToken.getHeader(ControllerSecurityToken.AUTHORIZATION_HEADER);
|
final String authHeader = controllerSecurityToken.getHeader(ControllerSecurityToken.AUTHORIZATION_HEADER);
|
||||||
@@ -63,7 +43,7 @@ public class GatewayTokenAuthenticator extends Authenticator.AbstractAuthenticat
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isEnabled(controllerSecurityToken)) {
|
if (!isEnabled(controllerSecurityToken)) {
|
||||||
log.debug("The gateway token authentication is disabled");
|
log.debug("The gateway token auth is disabled");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,8 +51,14 @@ public class GatewayTokenAuthenticator extends Authenticator.AbstractAuthenticat
|
|||||||
final String presentedToken = authHeader.substring(OFFSET_GATEWAY_TOKEN);
|
final String presentedToken = authHeader.substring(OFFSET_GATEWAY_TOKEN);
|
||||||
|
|
||||||
// validate if the presented token is the same as the gateway token
|
// validate if the presented token is the same as the gateway token
|
||||||
return presentedToken.equals(tenantAware.runAsTenant(controllerSecurityToken.getTenant(), gatewaySecurityTokenKeyGetter))
|
return presentedToken.equals(asSystemAsTenant(
|
||||||
? authenticatedController(controllerSecurityToken.getTenant(), controllerSecurityToken.getControllerId()) : null;
|
controllerSecurityToken.getTenant(),
|
||||||
|
() -> {
|
||||||
|
log.trace("retrieving configuration value for configuration key {}", AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY);
|
||||||
|
return TenantConfigHelper.getAsSystem(AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class);
|
||||||
|
}))
|
||||||
|
? authenticatedController(controllerSecurityToken.getTenant(), controllerSecurityToken.getControllerId())
|
||||||
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security.controller;
|
package org.eclipse.hawkbit.security.controller;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.context.AccessContext.asSystemAsTenant;
|
||||||
|
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_HEADER_AUTHORITY_NAME;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -29,7 +29,7 @@ import org.springframework.security.core.Authentication;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class SecurityHeaderAuthenticator extends Authenticator.AbstractAuthenticator {
|
public class SecurityHeaderAuthenticator extends Authenticator.AbstractAuthenticator {
|
||||||
|
|
||||||
private static final Logger LOG_SECURITY_AUTH = LoggerFactory.getLogger("server-security.authentication");
|
private static final Logger LOG_SECURITY_AUTH = LoggerFactory.getLogger("server-security.auth");
|
||||||
|
|
||||||
// Example Headers with Cert Information
|
// Example Headers with Cert Information
|
||||||
// Clientip: 217.24.201.180
|
// Clientip: 217.24.201.180
|
||||||
@@ -48,18 +48,9 @@ public class SecurityHeaderAuthenticator extends Authenticator.AbstractAuthentic
|
|||||||
// header exists multiple times in the request for all trusted chains.
|
// header exists multiple times in the request for all trusted chains.
|
||||||
private final String sslIssuerHashBasicHeader;
|
private final String sslIssuerHashBasicHeader;
|
||||||
|
|
||||||
private final Callable<String> sslIssuerNameConfigGetter;
|
public SecurityHeaderAuthenticator(final String caCommonNameHeader, final String caAuthorityNameHeader) {
|
||||||
|
|
||||||
public SecurityHeaderAuthenticator(
|
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
|
|
||||||
final SystemSecurityContext systemSecurityContext,
|
|
||||||
final String caCommonNameHeader, final String caAuthorityNameHeader) {
|
|
||||||
super(tenantConfigurationManagement, tenantAware, systemSecurityContext);
|
|
||||||
this.caCommonNameHeader = caCommonNameHeader;
|
this.caCommonNameHeader = caCommonNameHeader;
|
||||||
this.sslIssuerHashBasicHeader = caAuthorityNameHeader;
|
this.sslIssuerHashBasicHeader = caAuthorityNameHeader;
|
||||||
sslIssuerNameConfigGetter = () -> systemSecurityContext.runAsSystem(
|
|
||||||
() -> tenantConfigurationManagement.getConfigurationValue(
|
|
||||||
TenantConfigurationKey.AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class).getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -76,13 +67,15 @@ public class SecurityHeaderAuthenticator extends Authenticator.AbstractAuthentic
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isEnabled(controllerSecurityToken)) {
|
if (!isEnabled(controllerSecurityToken)) {
|
||||||
log.debug("The gateway header authentication is disabled");
|
log.debug("The gateway header auth is disabled");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String sslIssuerHashValue = getIssuerHashHeader(
|
final String sslIssuerHashValue = getIssuerHashHeader(
|
||||||
controllerSecurityToken,
|
controllerSecurityToken,
|
||||||
tenantAware.runAsTenant(controllerSecurityToken.getTenant(), sslIssuerNameConfigGetter));
|
asSystemAsTenant(
|
||||||
|
controllerSecurityToken.getTenant(),
|
||||||
|
() -> TenantConfigHelper.getAsSystem(AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class)));
|
||||||
if (sslIssuerHashValue == null) {
|
if (sslIssuerHashValue == null) {
|
||||||
log.debug("The request contains the 'common name' header but trusted hash is not found");
|
log.debug("The request contains the 'common name' header but trusted hash is not found");
|
||||||
return null;
|
return null;
|
||||||
@@ -115,7 +108,8 @@ public class SecurityHeaderAuthenticator extends Authenticator.AbstractAuthentic
|
|||||||
|
|
||||||
// iterate over the headers until we get a null header.
|
// iterate over the headers until we get a null header.
|
||||||
String foundHash;
|
String foundHash;
|
||||||
for (int iHeader = 1; (foundHash = controllerSecurityToken.getHeader(String.format(sslIssuerHashBasicHeader, iHeader))) != null; iHeader++) {
|
for (int iHeader = 1; (foundHash = controllerSecurityToken.getHeader(
|
||||||
|
String.format(sslIssuerHashBasicHeader, iHeader))) != null; iHeader++) {
|
||||||
if (knownHashes.contains(foundHash.toLowerCase())) {
|
if (knownHashes.contains(foundHash.toLowerCase())) {
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
log.trace("Found matching ssl issuer hash at position {}", iHeader);
|
log.trace("Found matching ssl issuer hash at position {}", iHeader);
|
||||||
|
|||||||
@@ -9,11 +9,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security.controller;
|
package org.eclipse.hawkbit.security.controller;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.context.AccessContext.asSystemAsTenant;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
@@ -32,11 +31,7 @@ public class SecurityTokenAuthenticator extends Authenticator.AbstractAuthentica
|
|||||||
|
|
||||||
private final ControllerManagement controllerManagement;
|
private final ControllerManagement controllerManagement;
|
||||||
|
|
||||||
public SecurityTokenAuthenticator(
|
public SecurityTokenAuthenticator(final ControllerManagement controllerManagement) {
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
|
|
||||||
final SystemSecurityContext systemSecurityContext,
|
|
||||||
final ControllerManagement controllerManagement) {
|
|
||||||
super(tenantConfigurationManagement, tenantAware, systemSecurityContext);
|
|
||||||
this.controllerManagement = controllerManagement;
|
this.controllerManagement = controllerManagement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,21 +47,20 @@ public class SecurityTokenAuthenticator extends Authenticator.AbstractAuthentica
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isEnabled(controllerSecurityToken)) {
|
if (!isEnabled(controllerSecurityToken)) {
|
||||||
log.debug("The target security token authentication is disabled");
|
log.debug("The target security token auth is disabled");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("Found 'authorization' header starting with '{}'", TARGET_SECURITY_TOKEN_AUTH_SCHEME);
|
log.debug("Found 'authorization' header starting with '{}'", TARGET_SECURITY_TOKEN_AUTH_SCHEME);
|
||||||
final String presentedToken = authHeader.substring(OFFSET_TARGET_TOKEN);
|
final String presentedToken = authHeader.substring(OFFSET_TARGET_TOKEN);
|
||||||
|
|
||||||
return systemSecurityContext.runAsSystemAsTenant(() -> controllerSecurityToken.getTargetId() != null
|
final String tenant = controllerSecurityToken.getTenant();
|
||||||
|
return asSystemAsTenant(tenant, () -> controllerSecurityToken.getTargetId() != null
|
||||||
? controllerManagement.find(controllerSecurityToken.getTargetId())
|
? controllerManagement.find(controllerSecurityToken.getTargetId())
|
||||||
: controllerManagement.findByControllerId(controllerSecurityToken.getControllerId()),
|
: controllerManagement.findByControllerId(controllerSecurityToken.getControllerId()))
|
||||||
controllerSecurityToken.getTenant())
|
|
||||||
// validate if the presented token is the same as the one set for the target
|
// validate if the presented token is the same as the one set for the target
|
||||||
.filter(target -> presentedToken.equals(
|
.filter(target -> presentedToken.equals(asSystemAsTenant(tenant, target::getSecurityToken)))
|
||||||
systemSecurityContext.runAsSystemAsTenant(target::getSecurityToken, controllerSecurityToken.getTenant())))
|
.map(target -> authenticatedController(tenant, target.getControllerId()))
|
||||||
.map(target -> authenticatedController(controllerSecurityToken.getTenant(), target.getControllerId()))
|
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,8 @@ import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationPrope
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.tenancy.UserAuthoritiesResolver;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@@ -28,7 +26,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Feature: Unit Tests - Security<br/>
|
* Feature: Unit Tests - Security<br/>
|
||||||
* Story: Gateway token authentication
|
* Story: Gateway token auth
|
||||||
*/
|
*/
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class GatewayTokenAuthenticatorTest {
|
class GatewayTokenAuthenticatorTest {
|
||||||
@@ -48,17 +46,15 @@ class GatewayTokenAuthenticatorTest {
|
|||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private TenantConfigurationManagement tenantConfigurationManagementMock;
|
private TenantConfigurationManagement tenantConfigurationManagementMock;
|
||||||
@Mock
|
|
||||||
private UserAuthoritiesResolver authoritiesResolver;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void before() {
|
void before() {
|
||||||
final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver);
|
TenantConfigHelper.setTenantConfigurationManagement(tenantConfigurationManagementMock);
|
||||||
authenticator = new GatewayTokenAuthenticator(tenantConfigurationManagementMock, tenantAware, new SystemSecurityContext(tenantAware));
|
authenticator = new GatewayTokenAuthenticator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests successful authentication with gateway token
|
* Tests successful auth with gateway token
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithGwToken() {
|
void testWithGwToken() {
|
||||||
@@ -74,7 +70,7 @@ class GatewayTokenAuthenticatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that if gateway token doesn't match, the authentication fails
|
* Tests that if gateway token doesn't match, the auth fails
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithBadGwToken() {
|
void testWithBadGwToken() {
|
||||||
@@ -88,7 +84,7 @@ class GatewayTokenAuthenticatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that if gateway token miss, the authentication fails
|
* Tests that if gateway token miss, the auth fails
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithoutGwToken() {
|
void testWithoutGwToken() {
|
||||||
@@ -96,7 +92,7 @@ class GatewayTokenAuthenticatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that if disabled, the authentication fails
|
* Tests that if disabled, the auth fails
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithGwTokenButDisabled() {
|
void testWithGwTokenButDisabled() {
|
||||||
|
|||||||
@@ -15,10 +15,8 @@ import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationPrope
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.tenancy.UserAuthoritiesResolver;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@@ -57,20 +55,15 @@ class SecurityHeaderAuthenticatorTest {
|
|||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private TenantConfigurationManagement tenantConfigurationManagementMock;
|
private TenantConfigurationManagement tenantConfigurationManagementMock;
|
||||||
@Mock
|
|
||||||
private UserAuthoritiesResolver authoritiesResolver;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void before() {
|
void before() {
|
||||||
final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver);
|
TenantConfigHelper.setTenantConfigurationManagement(tenantConfigurationManagementMock);
|
||||||
authenticator = new SecurityHeaderAuthenticator(
|
authenticator = new SecurityHeaderAuthenticator(CA_COMMON_NAME, "X-Ssl-Issuer-Hash-%d");
|
||||||
tenantConfigurationManagementMock, tenantAware,
|
|
||||||
new SystemSecurityContext(tenantAware), CA_COMMON_NAME, "X-Ssl-Issuer-Hash-%d"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests successful authentication with multiple a single hashes
|
* Tests successful auth with multiple a single hashes
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithSingleKnownHash() {
|
void testWithSingleKnownHash() {
|
||||||
@@ -86,7 +79,7 @@ class SecurityHeaderAuthenticatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests successful authentication with multiple hashes
|
* Tests successful auth with multiple hashes
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithMultipleKnownHashes() {
|
void testWithMultipleKnownHashes() {
|
||||||
@@ -107,7 +100,7 @@ class SecurityHeaderAuthenticatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that if the hash is unknown, the authentication fails
|
* Tests that if the hash is unknown, the auth fails
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithUnknownHash() {
|
void testWithUnknownHash() {
|
||||||
@@ -121,7 +114,7 @@ class SecurityHeaderAuthenticatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that if CN doesn't match the CN in the security token, the authentication fails
|
* Tests that if CN doesn't match the CN in the security token, the auth fails
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithNonMatchingCN() {
|
void testWithNonMatchingCN() {
|
||||||
@@ -133,7 +126,7 @@ class SecurityHeaderAuthenticatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that if the hash miss, the authentication fails
|
* Tests that if the hash miss, the auth fails
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithoutHash() {
|
void testWithoutHash() {
|
||||||
@@ -141,7 +134,7 @@ class SecurityHeaderAuthenticatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that if disabled, the authentication fails
|
* Tests that if disabled, the auth fails
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithSingleKnownHashButDisabled() {
|
void testWithSingleKnownHashButDisabled() {
|
||||||
|
|||||||
@@ -17,11 +17,9 @@ import java.util.Optional;
|
|||||||
|
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.tenancy.UserAuthoritiesResolver;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@@ -31,7 +29,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Feature: Unit Tests - Security<br/>
|
* Feature: Unit Tests - Security<br/>
|
||||||
* Story: Gateway token authentication
|
* Story: Gateway token auth
|
||||||
*/
|
*/
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class SecurityTokenAuthenticatorTest {
|
class SecurityTokenAuthenticatorTest {
|
||||||
@@ -51,19 +49,15 @@ class SecurityTokenAuthenticatorTest {
|
|||||||
private TenantConfigurationManagement tenantConfigurationManagementMock;
|
private TenantConfigurationManagement tenantConfigurationManagementMock;
|
||||||
@Mock
|
@Mock
|
||||||
private ControllerManagement controllerManagementMock;
|
private ControllerManagement controllerManagementMock;
|
||||||
@Mock
|
|
||||||
private UserAuthoritiesResolver authoritiesResolver;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void before() {
|
void before() {
|
||||||
final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver);
|
TenantConfigHelper.setTenantConfigurationManagement(tenantConfigurationManagementMock);
|
||||||
authenticator = new SecurityTokenAuthenticator(
|
authenticator = new SecurityTokenAuthenticator(controllerManagementMock);
|
||||||
tenantConfigurationManagementMock, tenantAware,
|
|
||||||
new SystemSecurityContext(tenantAware), controllerManagementMock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests successful authentication with gateway token
|
* Tests successful auth with gateway token
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithSecToken() {
|
void testWithSecToken() {
|
||||||
@@ -82,7 +76,7 @@ class SecurityTokenAuthenticatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that if gateway token doesn't match, the authentication fails
|
* Tests that if gateway token doesn't match, the auth fails
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithBadSecToken() {
|
void testWithBadSecToken() {
|
||||||
@@ -94,7 +88,7 @@ class SecurityTokenAuthenticatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that if gateway token miss, the authentication fails
|
* Tests that if gateway token miss, the auth fails
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithoutSecToken() {
|
void testWithoutSecToken() {
|
||||||
@@ -102,7 +96,7 @@ class SecurityTokenAuthenticatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that if disabled, the authentication fails
|
* Tests that if disabled, the auth fails
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testWithSecTokenButDisabled() {
|
void testWithSecTokenButDisabled() {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ server.servlet.encoding.charset=UTF-8
|
|||||||
server.servlet.encoding.enabled=true
|
server.servlet.encoding.enabled=true
|
||||||
server.servlet.encoding.force=true
|
server.servlet.encoding.force=true
|
||||||
|
|
||||||
# DDI authentication configuration
|
# DDI auth configuration
|
||||||
hawkbit.server.ddi.security.authentication.targettoken.enabled=false
|
hawkbit.server.ddi.security.authentication.targettoken.enabled=false
|
||||||
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false
|
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ package org.eclipse.hawkbit.app.ddi;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
import org.eclipse.hawkbit.auth.SpPermission;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpRole;
|
import org.eclipse.hawkbit.auth.SpRole;
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|||||||
@@ -12,20 +12,17 @@ package org.eclipse.hawkbit.autoconfigure.ddi;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.eclipse.hawkbit.context.Mdc;
|
||||||
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.rest.SecurityManagedConfiguration;
|
import org.eclipse.hawkbit.rest.SecurityManagedConfiguration;
|
||||||
import org.eclipse.hawkbit.rest.security.DosFilter;
|
import org.eclipse.hawkbit.rest.security.DosFilter;
|
||||||
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
|
||||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.MdcHandler;
|
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.security.controller.AuthenticationFilters;
|
import org.eclipse.hawkbit.security.controller.AuthenticationFilters;
|
||||||
|
import org.eclipse.hawkbit.security.controller.DdiSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.controller.GatewayTokenAuthenticator;
|
import org.eclipse.hawkbit.security.controller.GatewayTokenAuthenticator;
|
||||||
import org.eclipse.hawkbit.security.controller.SecurityHeaderAuthenticator;
|
import org.eclipse.hawkbit.security.controller.SecurityHeaderAuthenticator;
|
||||||
import org.eclipse.hawkbit.security.controller.SecurityTokenAuthenticator;
|
import org.eclipse.hawkbit.security.controller.SecurityTokenAuthenticator;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@@ -50,23 +47,15 @@ class ControllerDownloadSecurityConfiguration {
|
|||||||
DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/*";
|
DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/*";
|
||||||
|
|
||||||
private final ControllerManagement controllerManagement;
|
private final ControllerManagement controllerManagement;
|
||||||
private final TenantConfigurationManagement tenantConfigurationManagement;
|
|
||||||
private final TenantAware tenantAware;
|
|
||||||
private final DdiSecurityProperties ddiSecurityConfiguration;
|
private final DdiSecurityProperties ddiSecurityConfiguration;
|
||||||
private final HawkbitSecurityProperties securityProperties;
|
private final HawkbitSecurityProperties securityProperties;
|
||||||
private final SystemSecurityContext systemSecurityContext;
|
|
||||||
|
|
||||||
ControllerDownloadSecurityConfiguration(
|
ControllerDownloadSecurityConfiguration(
|
||||||
final ControllerManagement controllerManagement,
|
final ControllerManagement controllerManagement,
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
|
final DdiSecurityProperties ddiSecurityConfiguration, final HawkbitSecurityProperties securityProperties) {
|
||||||
final DdiSecurityProperties ddiSecurityConfiguration,
|
|
||||||
final HawkbitSecurityProperties securityProperties, final SystemSecurityContext systemSecurityContext) {
|
|
||||||
this.controllerManagement = controllerManagement;
|
this.controllerManagement = controllerManagement;
|
||||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
|
||||||
this.tenantAware = tenantAware;
|
|
||||||
this.ddiSecurityConfiguration = ddiSecurityConfiguration;
|
this.ddiSecurityConfiguration = ddiSecurityConfiguration;
|
||||||
this.securityProperties = securityProperties;
|
this.securityProperties = securityProperties;
|
||||||
this.systemSecurityContext = systemSecurityContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,17 +84,13 @@ class ControllerDownloadSecurityConfiguration {
|
|||||||
.csrf(AbstractHttpConfigurer::disable)
|
.csrf(AbstractHttpConfigurer::disable)
|
||||||
.addFilterBefore(new AuthenticationFilters.SecurityHeaderAuthenticationFilter(
|
.addFilterBefore(new AuthenticationFilters.SecurityHeaderAuthenticationFilter(
|
||||||
new SecurityHeaderAuthenticator(
|
new SecurityHeaderAuthenticator(
|
||||||
tenantConfigurationManagement, tenantAware, systemSecurityContext,
|
|
||||||
ddiSecurityConfiguration.getRp().getCnHeader(), ddiSecurityConfiguration.getRp().getSslIssuerHashHeader()),
|
ddiSecurityConfiguration.getRp().getCnHeader(), ddiSecurityConfiguration.getRp().getSslIssuerHashHeader()),
|
||||||
ddiSecurityConfiguration), AuthorizationFilter.class)
|
ddiSecurityConfiguration), AuthorizationFilter.class)
|
||||||
.addFilterBefore(new AuthenticationFilters.SecurityTokenAuthenticationFilter(
|
.addFilterBefore(new AuthenticationFilters.SecurityTokenAuthenticationFilter(
|
||||||
new SecurityTokenAuthenticator(
|
new SecurityTokenAuthenticator(controllerManagement),
|
||||||
tenantConfigurationManagement, tenantAware, systemSecurityContext,
|
|
||||||
controllerManagement),
|
|
||||||
ddiSecurityConfiguration), AuthorizationFilter.class)
|
ddiSecurityConfiguration), AuthorizationFilter.class)
|
||||||
.addFilterBefore(new AuthenticationFilters.GatewayTokenAuthenticationFilter(
|
.addFilterBefore(new AuthenticationFilters.GatewayTokenAuthenticationFilter(
|
||||||
new GatewayTokenAuthenticator(
|
new GatewayTokenAuthenticator(),
|
||||||
tenantConfigurationManagement, tenantAware, systemSecurityContext),
|
|
||||||
ddiSecurityConfiguration), AuthorizationFilter.class)
|
ddiSecurityConfiguration), AuthorizationFilter.class)
|
||||||
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(
|
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(
|
||||||
(request, response, authException) -> response.setStatus(HttpStatus.UNAUTHORIZED.value())))
|
(request, response, authException) -> response.setStatus(HttpStatus.UNAUTHORIZED.value())))
|
||||||
@@ -115,7 +100,7 @@ class ControllerDownloadSecurityConfiguration {
|
|||||||
http.redirectToHttps(Customizer.withDefaults());
|
http.redirectToHttps(Customizer.withDefaults());
|
||||||
}
|
}
|
||||||
|
|
||||||
MdcHandler.Filter.addMdcFilter(http);
|
Mdc.Filter.addMdcFilter(http);
|
||||||
|
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,20 +12,17 @@ package org.eclipse.hawkbit.autoconfigure.ddi;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.eclipse.hawkbit.context.Mdc;
|
||||||
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.rest.SecurityManagedConfiguration;
|
import org.eclipse.hawkbit.rest.SecurityManagedConfiguration;
|
||||||
import org.eclipse.hawkbit.rest.security.DosFilter;
|
import org.eclipse.hawkbit.rest.security.DosFilter;
|
||||||
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
|
||||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.MdcHandler;
|
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.security.controller.AuthenticationFilters;
|
import org.eclipse.hawkbit.security.controller.AuthenticationFilters;
|
||||||
|
import org.eclipse.hawkbit.security.controller.DdiSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.controller.GatewayTokenAuthenticator;
|
import org.eclipse.hawkbit.security.controller.GatewayTokenAuthenticator;
|
||||||
import org.eclipse.hawkbit.security.controller.SecurityHeaderAuthenticator;
|
import org.eclipse.hawkbit.security.controller.SecurityHeaderAuthenticator;
|
||||||
import org.eclipse.hawkbit.security.controller.SecurityTokenAuthenticator;
|
import org.eclipse.hawkbit.security.controller.SecurityTokenAuthenticator;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
@@ -52,23 +49,16 @@ class ControllerSecurityConfiguration {
|
|||||||
private static final String[] DDI_ANT_MATCHERS = { DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/**" };
|
private static final String[] DDI_ANT_MATCHERS = { DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/**" };
|
||||||
|
|
||||||
private final ControllerManagement controllerManagement;
|
private final ControllerManagement controllerManagement;
|
||||||
private final TenantConfigurationManagement tenantConfigurationManagement;
|
|
||||||
private final TenantAware tenantAware;
|
|
||||||
private final DdiSecurityProperties ddiSecurityConfiguration;
|
private final DdiSecurityProperties ddiSecurityConfiguration;
|
||||||
private final HawkbitSecurityProperties securityProperties;
|
private final HawkbitSecurityProperties securityProperties;
|
||||||
private final SystemSecurityContext systemSecurityContext;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
ControllerSecurityConfiguration(final ControllerManagement controllerManagement,
|
ControllerSecurityConfiguration(
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
|
final ControllerManagement controllerManagement, final DdiSecurityProperties ddiSecurityConfiguration,
|
||||||
final DdiSecurityProperties ddiSecurityConfiguration,
|
final HawkbitSecurityProperties securityProperties) {
|
||||||
final HawkbitSecurityProperties securityProperties, final SystemSecurityContext systemSecurityContext) {
|
|
||||||
this.controllerManagement = controllerManagement;
|
this.controllerManagement = controllerManagement;
|
||||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
|
||||||
this.tenantAware = tenantAware;
|
|
||||||
this.ddiSecurityConfiguration = ddiSecurityConfiguration;
|
this.ddiSecurityConfiguration = ddiSecurityConfiguration;
|
||||||
this.securityProperties = securityProperties;
|
this.securityProperties = securityProperties;
|
||||||
this.systemSecurityContext = systemSecurityContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,7 +79,6 @@ class ControllerSecurityConfiguration {
|
|||||||
return filterRegBean;
|
return filterRegBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Order(301)
|
@Order(301)
|
||||||
protected SecurityFilterChain filterChainDDI(
|
protected SecurityFilterChain filterChainDDI(
|
||||||
@@ -100,24 +89,23 @@ class ControllerSecurityConfiguration {
|
|||||||
.authorizeHttpRequests(amrmRegistry -> amrmRegistry.anyRequest().authenticated())
|
.authorizeHttpRequests(amrmRegistry -> amrmRegistry.anyRequest().authenticated())
|
||||||
.anonymous(AbstractHttpConfigurer::disable)
|
.anonymous(AbstractHttpConfigurer::disable)
|
||||||
.csrf(AbstractHttpConfigurer::disable)
|
.csrf(AbstractHttpConfigurer::disable)
|
||||||
.addFilterBefore(new AuthenticationFilters.SecurityHeaderAuthenticationFilter(
|
.addFilterBefore(
|
||||||
|
new AuthenticationFilters.SecurityHeaderAuthenticationFilter(
|
||||||
new SecurityHeaderAuthenticator(
|
new SecurityHeaderAuthenticator(
|
||||||
tenantConfigurationManagement, tenantAware,
|
ddiSecurityConfiguration.getRp().getCnHeader(),
|
||||||
systemSecurityContext, ddiSecurityConfiguration.getRp().getCnHeader(), ddiSecurityConfiguration.getRp().getSslIssuerHashHeader()
|
ddiSecurityConfiguration.getRp().getSslIssuerHashHeader()), ddiSecurityConfiguration),
|
||||||
), ddiSecurityConfiguration), AuthorizationFilter.class)
|
AuthorizationFilter.class)
|
||||||
.addFilterBefore(new AuthenticationFilters.SecurityTokenAuthenticationFilter(
|
.addFilterBefore(
|
||||||
new SecurityTokenAuthenticator(
|
new AuthenticationFilters.SecurityTokenAuthenticationFilter(
|
||||||
tenantConfigurationManagement, tenantAware,
|
new SecurityTokenAuthenticator(controllerManagement), ddiSecurityConfiguration),
|
||||||
systemSecurityContext, controllerManagement), ddiSecurityConfiguration), AuthorizationFilter.class)
|
AuthorizationFilter.class)
|
||||||
.addFilterBefore(new AuthenticationFilters.GatewayTokenAuthenticationFilter(
|
.addFilterBefore(
|
||||||
new GatewayTokenAuthenticator(
|
new AuthenticationFilters.GatewayTokenAuthenticationFilter(new GatewayTokenAuthenticator(), ddiSecurityConfiguration),
|
||||||
tenantConfigurationManagement, tenantAware,
|
AuthorizationFilter.class)
|
||||||
systemSecurityContext), ddiSecurityConfiguration), AuthorizationFilter.class)
|
|
||||||
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(
|
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(
|
||||||
(request, response, authException) -> response.setStatus(HttpStatus.UNAUTHORIZED.value())))
|
(request, response, authException) -> response.setStatus(HttpStatus.UNAUTHORIZED.value())))
|
||||||
.sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
|
.sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
|
||||||
|
|
||||||
|
|
||||||
if (securityProperties.getCors().isEnabled() && !disableCorsForDdiApi) {
|
if (securityProperties.getCors().isEnabled() && !disableCorsForDdiApi) {
|
||||||
http.cors(configurer -> configurer.configurationSource(securityProperties.getCors().toCorsConfigurationSource()));
|
http.cors(configurer -> configurer.configurationSource(securityProperties.getCors().toCorsConfigurationSource()));
|
||||||
}
|
}
|
||||||
@@ -126,7 +114,7 @@ class ControllerSecurityConfiguration {
|
|||||||
http.requiresChannel(crmRegistry -> crmRegistry.anyRequest().requiresSecure());
|
http.requiresChannel(crmRegistry -> crmRegistry.anyRequest().requiresSecure());
|
||||||
}
|
}
|
||||||
|
|
||||||
MdcHandler.Filter.addMdcFilter(http);
|
Mdc.Filter.addMdcFilter(http);
|
||||||
|
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
package org.eclipse.hawkbit.autoconfigure.ddi;
|
package org.eclipse.hawkbit.autoconfigure.ddi;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ddi.rest.resource.DdiApiConfiguration;
|
import org.eclipse.hawkbit.ddi.rest.resource.DdiApiConfiguration;
|
||||||
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
import org.eclipse.hawkbit.security.controller.DdiSecurityProperties;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|||||||
@@ -32,11 +32,6 @@
|
|||||||
<artifactId>hawkbit-core</artifactId>
|
<artifactId>hawkbit-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.hawkbit</groupId>
|
|
||||||
<artifactId>hawkbit-security-core</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
<artifactId>hawkbit-dmf-api</artifactId>
|
<artifactId>hawkbit-dmf-api</artifactId>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.amqp;
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.context.AccessContext.asSystem;
|
||||||
import static org.eclipse.hawkbit.repository.RepositoryConstants.MAX_ACTION_COUNT;
|
import static org.eclipse.hawkbit.repository.RepositoryConstants.MAX_ACTION_COUNT;
|
||||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.BATCH_ASSIGNMENTS_ENABLED;
|
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.BATCH_ASSIGNMENTS_ENABLED;
|
||||||
|
|
||||||
@@ -51,7 +52,6 @@ import org.eclipse.hawkbit.repository.RepositoryProperties;
|
|||||||
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent;
|
import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent;
|
import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent;
|
import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent;
|
||||||
@@ -64,6 +64,7 @@ import org.eclipse.hawkbit.repository.event.remote.service.MultiActionCancelServ
|
|||||||
import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistributionSetServiceEvent;
|
import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistributionSetServiceEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.service.TargetAttributesRequestedServiceEvent;
|
import org.eclipse.hawkbit.repository.event.remote.service.TargetAttributesRequestedServiceEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.service.TargetDeletedServiceEvent;
|
import org.eclipse.hawkbit.repository.event.remote.service.TargetDeletedServiceEvent;
|
||||||
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.ActionProperties;
|
import org.eclipse.hawkbit.repository.model.ActionProperties;
|
||||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||||
@@ -71,8 +72,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSet;
|
|||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.utils.IpUtil;
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
|
||||||
import org.springframework.amqp.core.Message;
|
import org.springframework.amqp.core.Message;
|
||||||
import org.springframework.amqp.core.MessageBuilder;
|
import org.springframework.amqp.core.MessageBuilder;
|
||||||
import org.springframework.amqp.core.MessageProperties;
|
import org.springframework.amqp.core.MessageProperties;
|
||||||
@@ -94,43 +94,36 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
|||||||
|
|
||||||
private final ArtifactUrlResolver artifactUrlHandler;
|
private final ArtifactUrlResolver artifactUrlHandler;
|
||||||
private final AmqpMessageSenderService amqpSenderService;
|
private final AmqpMessageSenderService amqpSenderService;
|
||||||
private final SystemSecurityContext systemSecurityContext;
|
|
||||||
private final SystemManagement systemManagement;
|
private final SystemManagement systemManagement;
|
||||||
private final TargetManagement<? extends Target> targetManagement;
|
private final TargetManagement<? extends Target> targetManagement;
|
||||||
private final SoftwareModuleManagement<? extends SoftwareModule> softwareModuleManagement;
|
private final SoftwareModuleManagement<? extends SoftwareModule> softwareModuleManagement;
|
||||||
private final DistributionSetManagement<? extends DistributionSet> distributionSetManagement;
|
private final DistributionSetManagement<? extends DistributionSet> distributionSetManagement;
|
||||||
private final DeploymentManagement deploymentManagement;
|
private final DeploymentManagement deploymentManagement;
|
||||||
private final TenantConfigurationManagement tenantConfigurationManagement;
|
|
||||||
private final RepositoryProperties repositoryProperties;
|
private final RepositoryProperties repositoryProperties;
|
||||||
|
|
||||||
@SuppressWarnings("java:S107")
|
@SuppressWarnings("java:S107")
|
||||||
protected AmqpMessageDispatcherService(
|
protected AmqpMessageDispatcherService(
|
||||||
final RabbitTemplate rabbitTemplate,
|
final RabbitTemplate rabbitTemplate,
|
||||||
final AmqpMessageSenderService amqpSenderService, final ArtifactUrlResolver artifactUrlHandler,
|
final AmqpMessageSenderService amqpSenderService, final ArtifactUrlResolver artifactUrlHandler,
|
||||||
final SystemSecurityContext systemSecurityContext, final SystemManagement systemManagement,
|
final SystemManagement systemManagement,
|
||||||
final TargetManagement<? extends Target> targetManagement,
|
final TargetManagement<? extends Target> targetManagement,
|
||||||
final SoftwareModuleManagement<? extends SoftwareModule> softwareModuleManagement,
|
final SoftwareModuleManagement<? extends SoftwareModule> softwareModuleManagement,
|
||||||
final DistributionSetManagement<? extends DistributionSet> distributionSetManagement,
|
final DistributionSetManagement<? extends DistributionSet> distributionSetManagement,
|
||||||
final DeploymentManagement deploymentManagement,
|
final DeploymentManagement deploymentManagement,
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement,
|
|
||||||
final RepositoryProperties repositoryProperties) {
|
final RepositoryProperties repositoryProperties) {
|
||||||
super(rabbitTemplate);
|
super(rabbitTemplate);
|
||||||
this.artifactUrlHandler = artifactUrlHandler;
|
this.artifactUrlHandler = artifactUrlHandler;
|
||||||
this.amqpSenderService = amqpSenderService;
|
this.amqpSenderService = amqpSenderService;
|
||||||
this.systemSecurityContext = systemSecurityContext;
|
|
||||||
this.systemManagement = systemManagement;
|
this.systemManagement = systemManagement;
|
||||||
this.targetManagement = targetManagement;
|
this.targetManagement = targetManagement;
|
||||||
this.softwareModuleManagement = softwareModuleManagement;
|
this.softwareModuleManagement = softwareModuleManagement;
|
||||||
this.distributionSetManagement = distributionSetManagement;
|
this.distributionSetManagement = distributionSetManagement;
|
||||||
this.deploymentManagement = deploymentManagement;
|
this.deploymentManagement = deploymentManagement;
|
||||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
|
||||||
this.repositoryProperties = repositoryProperties;
|
this.repositoryProperties = repositoryProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBatchAssignmentsEnabled() {
|
public boolean isBatchAssignmentsEnabled() {
|
||||||
return systemSecurityContext.runAsSystem(() ->
|
return TenantConfigHelper.getAsSystem(BATCH_ASSIGNMENTS_ENABLED, Boolean.class);
|
||||||
tenantConfigurationManagement
|
|
||||||
.getConfigurationValue(BATCH_ASSIGNMENTS_ENABLED, Boolean.class).getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -184,9 +177,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
|||||||
protected DmfDownloadAndUpdateRequest createDownloadAndUpdateRequest(
|
protected DmfDownloadAndUpdateRequest createDownloadAndUpdateRequest(
|
||||||
final Target target, final Long actionId, final Map<SoftwareModule, Map<String, String>> softwareModules) {
|
final Target target, final Long actionId, final Map<SoftwareModule, Map<String, String>> softwareModules) {
|
||||||
return new DmfDownloadAndUpdateRequest(
|
return new DmfDownloadAndUpdateRequest(
|
||||||
actionId,
|
actionId, asSystem(target::getSecurityToken), convertToAmqpSoftwareModules(target, softwareModules));
|
||||||
systemSecurityContext.runAsSystem(target::getSecurityToken),
|
|
||||||
convertToAmqpSoftwareModules(target, softwareModules));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -227,7 +218,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
|||||||
|
|
||||||
protected void sendPingResponseToDmfReceiver(final Message ping, final String tenant, final String virtualHost) {
|
protected void sendPingResponseToDmfReceiver(final Message ping, final String tenant, final String virtualHost) {
|
||||||
final Message message = MessageBuilder
|
final Message message = MessageBuilder
|
||||||
.withBody(String.valueOf(System.currentTimeMillis()).getBytes())
|
.withBody(String.valueOf(java.lang.System.currentTimeMillis()).getBytes())
|
||||||
.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)
|
.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)
|
||||||
.setCorrelationId(ping.getMessageProperties().getCorrelationId())
|
.setCorrelationId(ping.getMessageProperties().getCorrelationId())
|
||||||
.setHeader(MessageHeaderKey.TYPE, MessageType.PING_RESPONSE)
|
.setHeader(MessageHeaderKey.TYPE, MessageType.PING_RESPONSE)
|
||||||
@@ -251,16 +242,9 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
|||||||
amqpSenderService.sendMessage(message, address);
|
amqpSenderService.sendMessage(message, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DmfTarget convertToDmfTarget(final Target target, final Long actionId) {
|
|
||||||
return new DmfTarget(actionId, target.getControllerId(), systemSecurityContext.runAsSystem(target::getSecurityToken));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected DmfConfirmRequest createConfirmRequest(
|
protected DmfConfirmRequest createConfirmRequest(
|
||||||
final Target target, final Long actionId, final Map<SoftwareModule, Map<String, String>> softwareModules) {
|
final Target target, final Long actionId, final Map<SoftwareModule, Map<String, String>> softwareModules) {
|
||||||
return new DmfConfirmRequest(
|
return new DmfConfirmRequest(actionId, asSystem(target::getSecurityToken), convertToAmqpSoftwareModules(target, softwareModules));
|
||||||
actionId,
|
|
||||||
systemSecurityContext.runAsSystem(target::getSecurityToken),
|
|
||||||
convertToAmqpSoftwareModules(target, softwareModules));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendMultiActionRequestToTarget(
|
void sendMultiActionRequestToTarget(
|
||||||
@@ -580,13 +564,14 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
|||||||
final Map<SoftwareModule, Map<String, String>> modules) {
|
final Map<SoftwareModule, Map<String, String>> modules) {
|
||||||
final List<DmfTarget> dmfTargets = targets.stream()
|
final List<DmfTarget> dmfTargets = targets.stream()
|
||||||
.filter(target -> IpUtil.isAmqpUri(IpUtil.addressToUri(target.getAddress())))
|
.filter(target -> IpUtil.isAmqpUri(IpUtil.addressToUri(target.getAddress())))
|
||||||
.map(t -> convertToDmfTarget(t, actions.get(t.getControllerId()).getId()))
|
// as system - the security token is sent to DMF receiver
|
||||||
|
.map(t -> new DmfTarget(actions.get(t.getControllerId()).getId(), t.getControllerId(), asSystem(t::getSecurityToken)))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
// due to the fact that all targets in a batch use the same set of software modules we don't generate target-specific urls
|
// due to the fact that all targets in a batch use the same set of software modules we don't generate target-specific urls
|
||||||
final Target firstTarget = targets.get(0);
|
final Target firstTarget = targets.get(0);
|
||||||
final DmfBatchDownloadAndUpdateRequest batchRequest = new DmfBatchDownloadAndUpdateRequest(
|
final DmfBatchDownloadAndUpdateRequest batchRequest = new DmfBatchDownloadAndUpdateRequest(
|
||||||
System.currentTimeMillis(),
|
java.lang.System.currentTimeMillis(),
|
||||||
dmfTargets,
|
dmfTargets,
|
||||||
Optional.ofNullable(modules)
|
Optional.ofNullable(modules)
|
||||||
.map(Map::entrySet)
|
.map(Map::entrySet)
|
||||||
@@ -594,7 +579,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
|||||||
.map(stream -> stream.map(entry -> convertToAmqpSoftwareModule(firstTarget, entry)).toList())
|
.map(stream -> stream.map(entry -> convertToAmqpSoftwareModule(firstTarget, entry)).toList())
|
||||||
.orElse(null));
|
.orElse(null));
|
||||||
|
|
||||||
// we use only the first action when constructing message as Tenant and action type are the same
|
// we use only the first action when constructing message as AccessContext and action type are the same
|
||||||
// since all actions have the same trigger
|
// since all actions have the same trigger
|
||||||
final ActionProperties firstAction = actions.values().iterator().next();
|
final ActionProperties firstAction = actions.values().iterator().next();
|
||||||
final Message message = getMessageConverter().toMessage(
|
final Message message = getMessageConverter().toMessage(
|
||||||
|
|||||||
@@ -10,9 +10,7 @@
|
|||||||
package org.eclipse.hawkbit.amqp;
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
import static org.eclipse.hawkbit.repository.RepositoryConstants.MAX_ACTION_COUNT;
|
import static org.eclipse.hawkbit.repository.RepositoryConstants.MAX_ACTION_COUNT;
|
||||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -28,6 +26,7 @@ import jakarta.validation.constraints.NotNull;
|
|||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.audit.AuditLog;
|
import org.eclipse.hawkbit.audit.AuditLog;
|
||||||
|
import org.eclipse.hawkbit.auth.SpRole;
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
|
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
|
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
|
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
|
||||||
@@ -37,14 +36,13 @@ import org.eclipse.hawkbit.dmf.json.model.DmfAttributeUpdate;
|
|||||||
import org.eclipse.hawkbit.dmf.json.model.DmfAutoConfirmation;
|
import org.eclipse.hawkbit.dmf.json.model.DmfAutoConfirmation;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.DmfCreateThing;
|
import org.eclipse.hawkbit.dmf.json.model.DmfCreateThing;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.DmfUpdateMode;
|
import org.eclipse.hawkbit.dmf.json.model.DmfUpdateMode;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpRole;
|
|
||||||
import org.eclipse.hawkbit.repository.ConfirmationManagement;
|
import org.eclipse.hawkbit.repository.ConfirmationManagement;
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.repository.UpdateMode;
|
import org.eclipse.hawkbit.repository.UpdateMode;
|
||||||
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||||
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.ActionStatusCreate;
|
import org.eclipse.hawkbit.repository.model.Action.ActionStatusCreate;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.ActionStatusCreate.ActionStatusCreateBuilder;
|
import org.eclipse.hawkbit.repository.model.Action.ActionStatusCreate.ActionStatusCreateBuilder;
|
||||||
@@ -53,9 +51,9 @@ import org.eclipse.hawkbit.repository.model.ActionProperties;
|
|||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
|
||||||
|
import org.eclipse.hawkbit.utils.IpUtil;
|
||||||
import org.springframework.amqp.AmqpRejectAndDontRequeueException;
|
import org.springframework.amqp.AmqpRejectAndDontRequeueException;
|
||||||
import org.springframework.amqp.core.Message;
|
import org.springframework.amqp.core.Message;
|
||||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
@@ -82,30 +80,16 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
|
|
||||||
private final AmqpMessageDispatcherService amqpMessageDispatcherService;
|
private final AmqpMessageDispatcherService amqpMessageDispatcherService;
|
||||||
private final ConfirmationManagement confirmationManagement;
|
private final ConfirmationManagement confirmationManagement;
|
||||||
private final TenantConfigurationManagement tenantConfigurationManagement;
|
|
||||||
private final SystemSecurityContext systemSecurityContext;
|
|
||||||
private ControllerManagement controllerManagement;
|
private ControllerManagement controllerManagement;
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param rabbitTemplate for converting messages
|
|
||||||
* @param amqpMessageDispatcherService to sending events to DMF client
|
|
||||||
* @param controllerManagement for target repo access
|
|
||||||
* @param systemSecurityContext the system Security Context
|
|
||||||
* @param tenantConfigurationManagement the tenant configuration Management
|
|
||||||
* @param confirmationManagement the confirmation management
|
|
||||||
*/
|
|
||||||
public AmqpMessageHandlerService(
|
public AmqpMessageHandlerService(
|
||||||
final RabbitTemplate rabbitTemplate,
|
final RabbitTemplate rabbitTemplate,
|
||||||
final AmqpMessageDispatcherService amqpMessageDispatcherService,
|
final AmqpMessageDispatcherService amqpMessageDispatcherService,
|
||||||
final ControllerManagement controllerManagement, final SystemSecurityContext systemSecurityContext,
|
final ControllerManagement controllerManagement,
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement, final ConfirmationManagement confirmationManagement) {
|
final ConfirmationManagement confirmationManagement) {
|
||||||
super(rabbitTemplate);
|
super(rabbitTemplate);
|
||||||
this.amqpMessageDispatcherService = amqpMessageDispatcherService;
|
this.amqpMessageDispatcherService = amqpMessageDispatcherService;
|
||||||
this.controllerManagement = controllerManagement;
|
this.controllerManagement = controllerManagement;
|
||||||
this.systemSecurityContext = systemSecurityContext;
|
|
||||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
|
||||||
this.confirmationManagement = confirmationManagement;
|
this.confirmationManagement = confirmationManagement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,7 +315,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void sendUpdateCommandToTarget(final Target target) {
|
private void sendUpdateCommandToTarget(final Target target) {
|
||||||
if (isMultiAssignmentsEnabled()) {
|
if (TenantConfigHelper.getAsSystem(TenantConfigurationProperties.TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED, Boolean.class)) {
|
||||||
sendCurrentActionsAsMultiActionToTarget(target);
|
sendCurrentActionsAsMultiActionToTarget(target);
|
||||||
} else {
|
} else {
|
||||||
sendOldestActionToTarget(target);
|
sendOldestActionToTarget(target);
|
||||||
@@ -456,8 +440,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
} else if (actionUpdateStatus.getActionStatus() == DmfActionStatus.DENIED) {
|
} else if (actionUpdateStatus.getActionStatus() == DmfActionStatus.DENIED) {
|
||||||
updatedAction = confirmationManagement.denyAction(action.getId(), actionUpdateStatus.getCode(), messages);
|
updatedAction = confirmationManagement.denyAction(action.getId(), actionUpdateStatus.getCode(), messages);
|
||||||
} else {
|
} else {
|
||||||
final ActionStatusCreateBuilder actionStatus = ActionStatusCreate.builder().actionId(action.getId())
|
final ActionStatusCreateBuilder actionStatus = ActionStatusCreate.builder().actionId(action.getId()).status(status);
|
||||||
.status(status);
|
|
||||||
Optional.ofNullable(actionUpdateStatus.getCode()).ifPresentOrElse(
|
Optional.ofNullable(actionUpdateStatus.getCode()).ifPresentOrElse(
|
||||||
code -> {
|
code -> {
|
||||||
actionStatus.code(code);
|
actionStatus.code(code);
|
||||||
@@ -491,12 +474,4 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
|
|
||||||
return findActionWithDetails.get();
|
return findActionWithDetails.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isMultiAssignmentsEnabled() {
|
|
||||||
return getConfigValue(MULTI_ASSIGNMENTS_ENABLED, Boolean.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T extends Serializable> T getConfigValue(final String key, final Class<T> valueType) {
|
|
||||||
return systemSecurityContext.runAsSystem(() -> tenantConfigurationManagement.getConfigurationValue(key, valueType).getValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@ import java.net.URI;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.utils.IpUtil;
|
||||||
import org.springframework.amqp.core.Message;
|
import org.springframework.amqp.core.Message;
|
||||||
import org.springframework.amqp.rabbit.connection.CorrelationData;
|
import org.springframework.amqp.rabbit.connection.CorrelationData;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
|||||||
@@ -28,11 +28,9 @@ import org.eclipse.hawkbit.repository.RepositoryProperties;
|
|||||||
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.springframework.amqp.core.Binding;
|
import org.springframework.amqp.core.Binding;
|
||||||
import org.springframework.amqp.core.BindingBuilder;
|
import org.springframework.amqp.core.BindingBuilder;
|
||||||
import org.springframework.amqp.core.FanoutExchange;
|
import org.springframework.amqp.core.FanoutExchange;
|
||||||
@@ -150,7 +148,7 @@ public class DmfApiConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the DMF API receiver queue for authentication requests called by 3rd
|
* Create the DMF API receiver queue for auth requests called by 3rd
|
||||||
* party artifact storages for download authorization by devices.
|
* party artifact storages for download authorization by devices.
|
||||||
*
|
*
|
||||||
* @return the receiver queue
|
* @return the receiver queue
|
||||||
@@ -227,12 +225,10 @@ public class DmfApiConfiguration {
|
|||||||
public AmqpMessageHandlerService amqpMessageHandlerService(
|
public AmqpMessageHandlerService amqpMessageHandlerService(
|
||||||
final RabbitTemplate rabbitTemplate,
|
final RabbitTemplate rabbitTemplate,
|
||||||
final AmqpMessageDispatcherService amqpMessageDispatcherService,
|
final AmqpMessageDispatcherService amqpMessageDispatcherService,
|
||||||
final ControllerManagement controllerManagement, final SystemSecurityContext systemSecurityContext,
|
final ControllerManagement controllerManagement,
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement,
|
|
||||||
final ConfirmationManagement confirmationManagement) {
|
final ConfirmationManagement confirmationManagement) {
|
||||||
return new AmqpMessageHandlerService(
|
return new AmqpMessageHandlerService(
|
||||||
rabbitTemplate, amqpMessageDispatcherService, controllerManagement,
|
rabbitTemplate, amqpMessageDispatcherService, controllerManagement, confirmationManagement);
|
||||||
systemSecurityContext, tenantConfigurationManagement, confirmationManagement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -266,14 +262,14 @@ public class DmfApiConfiguration {
|
|||||||
AmqpMessageDispatcherService amqpMessageDispatcherService(
|
AmqpMessageDispatcherService amqpMessageDispatcherService(
|
||||||
final RabbitTemplate rabbitTemplate,
|
final RabbitTemplate rabbitTemplate,
|
||||||
final AmqpMessageSenderService amqpSenderService, final ArtifactUrlResolver artifactUrlHandler,
|
final AmqpMessageSenderService amqpSenderService, final ArtifactUrlResolver artifactUrlHandler,
|
||||||
final SystemSecurityContext systemSecurityContext, final SystemManagement systemManagement,
|
final SystemManagement systemManagement,
|
||||||
final TargetManagement<? extends Target> targetManagement,
|
final TargetManagement<? extends Target> targetManagement,
|
||||||
final DistributionSetManagement<? extends DistributionSet> distributionSetManagement,
|
final DistributionSetManagement<? extends DistributionSet> distributionSetManagement,
|
||||||
final SoftwareModuleManagement<? extends SoftwareModule> softwareModuleManagement, final DeploymentManagement deploymentManagement,
|
final SoftwareModuleManagement<? extends SoftwareModule> softwareModuleManagement, final DeploymentManagement deploymentManagement,
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement, final RepositoryProperties repositoryProperties) {
|
final RepositoryProperties repositoryProperties) {
|
||||||
return new AmqpMessageDispatcherService(rabbitTemplate, amqpSenderService, artifactUrlHandler,
|
return new AmqpMessageDispatcherService(rabbitTemplate, amqpSenderService, artifactUrlHandler,
|
||||||
systemSecurityContext, systemManagement, targetManagement, softwareModuleManagement, distributionSetManagement,
|
systemManagement, targetManagement, softwareModuleManagement, distributionSetManagement,
|
||||||
deploymentManagement, tenantConfigurationManagement, repositoryProperties);
|
deploymentManagement, repositoryProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {
|
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ import org.eclipse.hawkbit.repository.model.Target;
|
|||||||
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
||||||
import org.eclipse.hawkbit.repository.test.util.AbstractIntegrationTest;
|
import org.eclipse.hawkbit.repository.test.util.AbstractIntegrationTest;
|
||||||
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.utils.IpUtil;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
@@ -116,8 +116,8 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
|||||||
when(systemManagement.getTenantMetadataWithoutDetails()).thenReturn(tenantMetaData);
|
when(systemManagement.getTenantMetadataWithoutDetails()).thenReturn(tenantMetaData);
|
||||||
|
|
||||||
amqpMessageDispatcherService = new AmqpMessageDispatcherService(rabbitTemplate, senderService,
|
amqpMessageDispatcherService = new AmqpMessageDispatcherService(rabbitTemplate, senderService,
|
||||||
artifactUrlHandlerMock, systemSecurityContext, systemManagement, targetManagement,
|
artifactUrlHandlerMock, systemManagement, targetManagement,
|
||||||
softwareModuleManagement, distributionSetManagement, deploymentManagement, tenantConfigurationManagement, repositoryProperties);
|
softwareModuleManagement, distributionSetManagement, deploymentManagement, repositoryProperties);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import static org.mockito.Mockito.times;
|
|||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -40,16 +39,12 @@ import org.eclipse.hawkbit.repository.ControllerManagement;
|
|||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.repository.UpdateMode;
|
import org.eclipse.hawkbit.repository.UpdateMode;
|
||||||
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
||||||
import org.eclipse.hawkbit.repository.SecurityTokenGeneratorHolder;
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.ActionProperties;
|
import org.eclipse.hawkbit.repository.model.ActionProperties;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
|
||||||
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
|
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.tenancy.UserAuthoritiesResolver;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@@ -93,8 +88,6 @@ class AmqpMessageHandlerServiceTest {
|
|||||||
private TenantConfigurationManagement tenantConfigurationManagement;
|
private TenantConfigurationManagement tenantConfigurationManagement;
|
||||||
@Mock
|
@Mock
|
||||||
private RabbitTemplate rabbitTemplate;
|
private RabbitTemplate rabbitTemplate;
|
||||||
@Mock
|
|
||||||
private UserAuthoritiesResolver authoritiesResolver;
|
|
||||||
|
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<Map<String, String>> attributesCaptor;
|
private ArgumentCaptor<Map<String, String>> attributesCaptor;
|
||||||
@@ -116,6 +109,7 @@ class AmqpMessageHandlerServiceTest {
|
|||||||
@BeforeEach
|
@BeforeEach
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
void before() {
|
void before() {
|
||||||
|
TenantConfigHelper.setTenantConfigurationManagement(tenantConfigurationManagement);
|
||||||
messageConverter = new Jackson2JsonMessageConverter();
|
messageConverter = new Jackson2JsonMessageConverter();
|
||||||
lenient().when(rabbitTemplate.getMessageConverter()).thenReturn(messageConverter);
|
lenient().when(rabbitTemplate.getMessageConverter()).thenReturn(messageConverter);
|
||||||
final TenantConfigurationValue multiAssignmentConfig = TenantConfigurationValue.builder().value(Boolean.FALSE)
|
final TenantConfigurationValue multiAssignmentConfig = TenantConfigurationValue.builder().value(Boolean.FALSE)
|
||||||
@@ -123,12 +117,8 @@ class AmqpMessageHandlerServiceTest {
|
|||||||
lenient().when(tenantConfigurationManagement.getConfigurationValue(MULTI_ASSIGNMENTS_ENABLED, Boolean.class))
|
lenient().when(tenantConfigurationManagement.getConfigurationValue(MULTI_ASSIGNMENTS_ENABLED, Boolean.class))
|
||||||
.thenReturn(multiAssignmentConfig);
|
.thenReturn(multiAssignmentConfig);
|
||||||
|
|
||||||
final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver);
|
amqpMessageHandlerService = new AmqpMessageHandlerService(
|
||||||
final SystemSecurityContext systemSecurityContext = new SystemSecurityContext(tenantAware);
|
rabbitTemplate, amqpMessageDispatcherServiceMock, controllerManagementMock, confirmationManagementMock);
|
||||||
|
|
||||||
amqpMessageHandlerService = new AmqpMessageHandlerService(rabbitTemplate, amqpMessageDispatcherServiceMock,
|
|
||||||
controllerManagementMock, systemSecurityContext, tenantConfigurationManagement,
|
|
||||||
confirmationManagementMock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -442,7 +432,7 @@ class AmqpMessageHandlerServiceTest {
|
|||||||
* Test next update is provided on finished action
|
* Test next update is provided on finished action
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void lookupNextUpdateActionAfterFinished() throws IllegalAccessException {
|
void lookupNextUpdateActionAfterFinished() {
|
||||||
|
|
||||||
// Mock
|
// Mock
|
||||||
final Action action = createActionWithTarget(22L);
|
final Action action = createActionWithTarget(22L);
|
||||||
@@ -655,10 +645,7 @@ class AmqpMessageHandlerServiceTest {
|
|||||||
return messageProperties;
|
return messageProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Action createActionWithTarget(final Long targetId) throws IllegalAccessException {
|
private Action createActionWithTarget(final Long targetId) {
|
||||||
// is needed for the creation of targets
|
|
||||||
initializeSecurityTokenGenerator();
|
|
||||||
|
|
||||||
// Mock
|
// Mock
|
||||||
final Action actionMock = mock(Action.class);
|
final Action actionMock = mock(Action.class);
|
||||||
final Target targetMock = mock(Target.class);
|
final Target targetMock = mock(Target.class);
|
||||||
@@ -673,17 +660,6 @@ class AmqpMessageHandlerServiceTest {
|
|||||||
return actionMock;
|
return actionMock;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeSecurityTokenGenerator() throws IllegalAccessException {
|
|
||||||
final SecurityTokenGeneratorHolder instance = SecurityTokenGeneratorHolder.getInstance();
|
|
||||||
final Field[] fields = instance.getClass().getDeclaredFields();
|
|
||||||
for (final Field field : fields) {
|
|
||||||
if (field.getType().isAssignableFrom(SecurityTokenGenerator.class)) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(instance, new SecurityTokenGenerator());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MessageProperties getThingCreatedMessageProperties(final String thingId) {
|
private MessageProperties getThingCreatedMessageProperties(final String thingId) {
|
||||||
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED);
|
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED);
|
||||||
messageProperties.setHeader(MessageHeaderKey.THING_ID, thingId);
|
messageProperties.setHeader(MessageHeaderKey.THING_ID, thingId);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ import org.eclipse.hawkbit.repository.model.Target;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch;
|
import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch;
|
||||||
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.utils.IpUtil;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.springframework.amqp.core.Message;
|
import org.springframework.amqp.core.Message;
|
||||||
@@ -93,9 +93,9 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected <T> T waitUntilIsPresent(final Callable<Optional<T>> callable) {
|
protected <T> T waitUntilIsPresent(final Callable<Optional<T>> callable) {
|
||||||
await().until(() -> SecurityContextSwitch.callAsPrivileged(() -> callable.call().isPresent()));
|
await().until(() -> SecurityContextSwitch.asPrivileged(() -> callable.call().isPresent()));
|
||||||
try {
|
try {
|
||||||
return SecurityContextSwitch.callAsPrivileged(() -> callable.call().get());
|
return SecurityContextSwitch.asPrivileged(() -> callable.call().get());
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -368,7 +368,7 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
|
|||||||
waitUntilIsPresent(() -> controllerManagement.findByControllerId(controllerId));
|
waitUntilIsPresent(() -> controllerManagement.findByControllerId(controllerId));
|
||||||
await().untilAsserted(() -> {
|
await().untilAsserted(() -> {
|
||||||
try {
|
try {
|
||||||
final Map<String, String> controllerAttributes = SecurityContextSwitch.callAsPrivileged(
|
final Map<String, String> controllerAttributes = SecurityContextSwitch.asPrivileged(
|
||||||
() -> targetManagement.getControllerAttributes(controllerId));
|
() -> targetManagement.getControllerAttributes(controllerId));
|
||||||
assertThat(controllerAttributes).hasSameSizeAs(attributes);
|
assertThat(controllerAttributes).hasSameSizeAs(attributes);
|
||||||
assertThat(controllerAttributes).containsAllEntriesOf(attributes);
|
assertThat(controllerAttributes).containsAllEntriesOf(attributes);
|
||||||
|
|||||||
@@ -793,7 +793,7 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void waitUntil(final Callable<Boolean> callable) {
|
private void waitUntil(final Callable<Boolean> callable) {
|
||||||
await().until(() -> SecurityContextSwitch.callAsPrivileged(callable));
|
await().until(() -> SecurityContextSwitch.asPrivileged(callable));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertLatestMultiActionMessageContainsInstallMessages(final String controllerId,
|
private void assertLatestMultiActionMessageContainsInstallMessages(final String controllerId,
|
||||||
|
|||||||
@@ -1231,7 +1231,7 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
|
|||||||
private void assertAction(final Long actionId, final int messages, final Status... expectedActionStates) {
|
private void assertAction(final Long actionId, final int messages, final Status... expectedActionStates) {
|
||||||
await().untilAsserted(() -> {
|
await().untilAsserted(() -> {
|
||||||
try {
|
try {
|
||||||
SecurityContextSwitch.callAsPrivileged(() -> {
|
SecurityContextSwitch.asPrivileged(() -> {
|
||||||
final List<ActionStatus> actionStatusList = deploymentManagement.findActionStatusByAction(actionId, PAGE).getContent();
|
final List<ActionStatus> actionStatusList = deploymentManagement.findActionStatusByAction(actionId, PAGE).getContent();
|
||||||
|
|
||||||
// Check correlation ID
|
// Check correlation ID
|
||||||
@@ -1265,7 +1265,7 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
|
|||||||
final Status... expectedActionStates) {
|
final Status... expectedActionStates) {
|
||||||
await().untilAsserted(() -> {
|
await().untilAsserted(() -> {
|
||||||
try {
|
try {
|
||||||
SecurityContextSwitch.callAsPrivileged(() -> {
|
SecurityContextSwitch.asPrivileged(() -> {
|
||||||
final List<ActionStatus> actionStatusList = deploymentManagement
|
final List<ActionStatus> actionStatusList = deploymentManagement
|
||||||
.findActionStatusByAction(actionId, PAGE).getContent();
|
.findActionStatusByAction(actionId, PAGE).getContent();
|
||||||
assertThat(actionStatusList).hasSize(statusListCount);
|
assertThat(actionStatusList).hasSize(statusListCount);
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import java.util.concurrent.Executors;
|
|||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.helper.SystemSecurityContextHolder;
|
|
||||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
@@ -39,11 +38,6 @@ public class AmqpTestConfiguration {
|
|||||||
return rabbitTemplate;
|
return rabbitTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
SystemSecurityContextHolder systemSecurityContextHolder() {
|
|
||||||
return SystemSecurityContextHolder.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
Executor asyncExecutor() {
|
Executor asyncExecutor() {
|
||||||
return new DelegatingSecurityContextExecutorService(Executors.newSingleThreadExecutor());
|
return new DelegatingSecurityContextExecutorService(Executors.newSingleThreadExecutor());
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ package org.eclipse.hawkbit.mgmt.rest.api;
|
|||||||
|
|
||||||
import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.ACTION_ORDER;
|
import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.ACTION_ORDER;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.extensions.Extension;
|
import io.swagger.v3.oas.annotations.extensions.Extension;
|
||||||
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
|
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
|
||||||
@@ -32,8 +34,6 @@ import org.springframework.web.bind.annotation.PathVariable;
|
|||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* REST API providing (read-only) access to actions.
|
* REST API providing (read-only) access to actions.
|
||||||
*/
|
*/
|
||||||
@@ -60,7 +60,7 @@ public interface MgmtActionRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -116,7 +116,7 @@ public interface MgmtActionRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "404", description = "Target not found.",
|
@ApiResponse(responseCode = "404", description = "Target not found.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@@ -140,7 +140,7 @@ public interface MgmtActionRestApi {
|
|||||||
@ApiResponses(value = {
|
@ApiResponses(value = {
|
||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or data volume restriction applies.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or data volume restriction applies.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "404", description = "Action not found.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
@ApiResponse(responseCode = "404", description = "Action not found.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@@ -160,7 +160,7 @@ public interface MgmtActionRestApi {
|
|||||||
@ApiResponses(value = {
|
@ApiResponses(value = {
|
||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or data volume restriction applies.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or data volume restriction applies.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
@ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -126,7 +126,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -159,7 +159,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -195,7 +195,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -226,7 +226,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -272,7 +272,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -331,7 +331,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -390,7 +390,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -448,7 +448,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "200", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -488,7 +488,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -527,7 +527,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -559,7 +559,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -593,7 +593,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully updated"),
|
@ApiResponse(responseCode = "200", description = "Successfully updated"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -633,7 +633,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -668,7 +668,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -709,7 +709,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -747,7 +747,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -796,7 +796,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -829,7 +829,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -861,7 +861,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -894,7 +894,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -930,7 +930,7 @@ public interface MgmtDistributionSetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully invalidated distribution set"),
|
@ApiResponse(responseCode = "204", description = "Successfully invalidated distribution set"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public interface MgmtDistributionSetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -115,7 +115,7 @@ public interface MgmtDistributionSetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -148,7 +148,7 @@ public interface MgmtDistributionSetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -186,7 +186,7 @@ public interface MgmtDistributionSetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -227,7 +227,7 @@ public interface MgmtDistributionSetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -269,7 +269,7 @@ public interface MgmtDistributionSetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -324,7 +324,7 @@ public interface MgmtDistributionSetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -362,7 +362,7 @@ public interface MgmtDistributionSetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -404,7 +404,7 @@ public interface MgmtDistributionSetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -439,7 +439,7 @@ public interface MgmtDistributionSetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -117,7 +117,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -150,7 +150,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -182,7 +182,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -225,7 +225,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -264,7 +264,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -301,7 +301,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -338,7 +338,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -374,7 +374,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -410,7 +410,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully removed"),
|
@ApiResponse(responseCode = "204", description = "Successfully removed"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -447,7 +447,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully removed"),
|
@ApiResponse(responseCode = "204", description = "Successfully removed"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -484,7 +484,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully added"),
|
@ApiResponse(responseCode = "204", description = "Successfully added"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -528,7 +528,7 @@ public interface MgmtDistributionSetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully added"),
|
@ApiResponse(responseCode = "204", description = "Successfully added"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public final class MgmtRestConstants {
|
|||||||
*/
|
*/
|
||||||
public static final String ROLLOUT_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/rollouts";
|
public static final String ROLLOUT_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/rollouts";
|
||||||
/**
|
/**
|
||||||
* The basic authentication validation mapping
|
* The basic auth validation mapping
|
||||||
*/
|
*/
|
||||||
public static final String AUTH_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/userinfo";
|
public static final String AUTH_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/userinfo";
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -119,7 +119,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -152,7 +152,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -191,7 +191,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -234,7 +234,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully approved"),
|
@ApiResponse(responseCode = "204", description = "Successfully approved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -268,7 +268,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully denied"),
|
@ApiResponse(responseCode = "204", description = "Successfully denied"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -300,7 +300,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully started"),
|
@ApiResponse(responseCode = "204", description = "Successfully started"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -330,7 +330,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully paused"),
|
@ApiResponse(responseCode = "204", description = "Successfully paused"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -361,7 +361,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully stopped"),
|
@ApiResponse(responseCode = "204", description = "Successfully stopped"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -394,7 +394,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -426,7 +426,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully resumed"),
|
@ApiResponse(responseCode = "204", description = "Successfully resumed"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -462,7 +462,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -520,7 +520,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -561,7 +561,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -616,7 +616,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully triggered"),
|
@ApiResponse(responseCode = "204", description = "Successfully triggered"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -646,7 +646,7 @@ public interface MgmtRolloutRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -113,7 +113,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -148,7 +148,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -183,7 +183,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -220,7 +220,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -270,7 +270,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -302,7 +302,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -336,7 +336,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -375,7 +375,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -405,7 +405,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -441,7 +441,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -473,7 +473,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -507,7 +507,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -539,7 +539,7 @@ public interface MgmtSoftwareModuleRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public interface MgmtSoftwareModuleTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -116,7 +116,7 @@ public interface MgmtSoftwareModuleTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -149,7 +149,7 @@ public interface MgmtSoftwareModuleTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -182,7 +182,7 @@ public interface MgmtSoftwareModuleTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -225,7 +225,7 @@ public interface MgmtSoftwareModuleTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public interface MgmtTargetFilterQueryRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -95,7 +95,7 @@ public interface MgmtTargetFilterQueryRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -147,7 +147,7 @@ public interface MgmtTargetFilterQueryRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -187,7 +187,7 @@ public interface MgmtTargetFilterQueryRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -227,7 +227,7 @@ public interface MgmtTargetFilterQueryRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -257,7 +257,7 @@ public interface MgmtTargetFilterQueryRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -289,7 +289,7 @@ public interface MgmtTargetFilterQueryRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -331,7 +331,7 @@ public interface MgmtTargetFilterQueryRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.mgmt.rest.api;
|
package org.eclipse.hawkbit.mgmt.rest.api;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.TARGET_GROUP_ORDER;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.extensions.Extension;
|
import io.swagger.v3.oas.annotations.extensions.Extension;
|
||||||
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
|
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
|
||||||
@@ -31,10 +35,6 @@ import org.springframework.web.bind.annotation.PutMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.TARGET_GROUP_ORDER;
|
|
||||||
|
|
||||||
@Tag(
|
@Tag(
|
||||||
name = "Target Groups", description = "REST API for Target Groups operations.",
|
name = "Target Groups", description = "REST API for Target Groups operations.",
|
||||||
extensions = @Extension(name = OpenApi.X_HAWKBIT, properties = @ExtensionProperty(name = "order", value = TARGET_GROUP_ORDER)))
|
extensions = @Extension(name = OpenApi.X_HAWKBIT, properties = @ExtensionProperty(name = "order", value = TARGET_GROUP_ORDER)))
|
||||||
@@ -60,7 +60,7 @@ public interface MgmtTargetGroupRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
@@ -113,7 +113,7 @@ public interface MgmtTargetGroupRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
@@ -163,7 +163,7 @@ public interface MgmtTargetGroupRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
@@ -199,7 +199,7 @@ public interface MgmtTargetGroupRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
@@ -235,7 +235,7 @@ public interface MgmtTargetGroupRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
@@ -268,7 +268,7 @@ public interface MgmtTargetGroupRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
@@ -295,7 +295,7 @@ public interface MgmtTargetGroupRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
@@ -320,7 +320,7 @@ public interface MgmtTargetGroupRestApi {
|
|||||||
description = "Handles the GET request of retrieving a list of all target groups.")
|
description = "Handles the GET request of retrieving a list of all target groups.")
|
||||||
@ApiResponses(value = {
|
@ApiResponses(value = {
|
||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
@@ -345,7 +345,7 @@ public interface MgmtTargetGroupRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTargetRequestBody;
|
|||||||
import org.eclipse.hawkbit.rest.OpenApi;
|
import org.eclipse.hawkbit.rest.OpenApi;
|
||||||
import org.eclipse.hawkbit.rest.json.model.ExceptionInfo;
|
import org.eclipse.hawkbit.rest.json.model.ExceptionInfo;
|
||||||
import org.springframework.hateoas.MediaTypes;
|
import org.springframework.hateoas.MediaTypes;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
@@ -53,7 +52,6 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API for handling target operations.
|
* API for handling target operations.
|
||||||
@@ -76,7 +74,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -112,7 +110,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -163,7 +161,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -202,7 +200,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -242,7 +240,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -272,7 +270,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -299,7 +297,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -326,7 +324,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -362,7 +360,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -418,7 +416,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted."),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted."),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -453,7 +451,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -487,7 +485,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Success"),
|
@ApiResponse(responseCode = "204", description = "Success"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -521,7 +519,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully updated"),
|
@ApiResponse(responseCode = "200", description = "Successfully updated"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -564,7 +562,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully updated confirmation status of the action"),
|
@ApiResponse(responseCode = "204", description = "Successfully updated confirmation status of the action"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies.",
|
"changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -612,7 +610,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -647,7 +645,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -680,7 +678,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "200", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -726,7 +724,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -753,7 +751,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@Operation(summary = "Return tags for specific target", description = "Get a paged list of tags for a target. Required permission: READ_REPOSITORY")
|
@Operation(summary = "Return tags for specific target", description = "Get a paged list of tags for a target. Required permission: READ_REPOSITORY")
|
||||||
@ApiResponses(value = {
|
@ApiResponses(value = {
|
||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -783,7 +781,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -819,7 +817,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -850,7 +848,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -883,7 +881,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully updated"),
|
@ApiResponse(responseCode = "204", description = "Successfully updated"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or data volume restriction applies.",
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -921,7 +919,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -950,7 +948,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or data volume restriction applies.",
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or data volume restriction applies.",
|
||||||
@@ -980,7 +978,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully activated auto-confirm"),
|
@ApiResponse(responseCode = "204", description = "Successfully activated auto-confirm"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -1017,7 +1015,7 @@ public interface MgmtTargetRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deactivated auto-confirm"),
|
@ApiResponse(responseCode = "204", description = "Successfully deactivated auto-confirm"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
@@ -109,7 +109,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "404", description = "Target tag not found.",
|
@ApiResponse(responseCode = "404", description = "Target tag not found.",
|
||||||
@@ -136,7 +136,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
@@ -165,7 +165,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully updated"),
|
@ApiResponse(responseCode = "200", description = "Successfully updated"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "404", description = "Target tag not found.",
|
@ApiResponse(responseCode = "404", description = "Target tag not found.",
|
||||||
@@ -198,7 +198,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "404", description = "Target tag not found.",
|
@ApiResponse(responseCode = "404", description = "Target tag not found.",
|
||||||
@@ -228,7 +228,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "404", description = "Target tag not found",
|
@ApiResponse(responseCode = "404", description = "Target tag not found",
|
||||||
@@ -277,7 +277,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."),
|
||||||
@@ -308,7 +308,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully assigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "404", description = "Not Found - e.g. target tag not found. Contains info about not found.",
|
@ApiResponse(responseCode = "404", description = "Not Found - e.g. target tag not found. Contains info about not found.",
|
||||||
@@ -344,7 +344,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "404", description = "Target not found.",
|
@ApiResponse(responseCode = "404", description = "Target not found.",
|
||||||
@@ -373,7 +373,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
@ApiResponse(responseCode = "204", description = "Successfully unassigned"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication."),
|
@ApiResponse(responseCode = "401", description = "The request requires user auth."),
|
||||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||||
"changed (i.e. read-only) or data volume restriction applies."),
|
"changed (i.e. read-only) or data volume restriction applies."),
|
||||||
@ApiResponse(responseCode = "404", description = "Not Found - e.g. target tag not found. Contains info about not found.",
|
@ApiResponse(responseCode = "404", description = "Not Found - e.g. target tag not found. Contains info about not found.",
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public interface MgmtTargetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -116,7 +116,7 @@ public interface MgmtTargetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -148,7 +148,7 @@ public interface MgmtTargetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -180,7 +180,7 @@ public interface MgmtTargetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully updated"),
|
@ApiResponse(responseCode = "200", description = "Successfully updated"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -222,7 +222,7 @@ public interface MgmtTargetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
@ApiResponse(responseCode = "201", description = "Successfully created"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -262,7 +262,7 @@ public interface MgmtTargetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -297,7 +297,7 @@ public interface MgmtTargetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully removed"),
|
@ApiResponse(responseCode = "204", description = "Successfully removed"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -333,7 +333,7 @@ public interface MgmtTargetTypeRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully added"),
|
@ApiResponse(responseCode = "204", description = "Successfully added"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public interface MgmtTenantManagementRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -88,7 +88,7 @@ public interface MgmtTenantManagementRestApi {
|
|||||||
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
@ApiResponse(responseCode = "204", description = "Successfully deleted"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -120,7 +120,7 @@ public interface MgmtTenantManagementRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -156,7 +156,7 @@ public interface MgmtTenantManagementRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
@@ -198,7 +198,7 @@ public interface MgmtTenantManagementRestApi {
|
|||||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
@ApiResponse(responseCode = "401", description = "The request requires user auth.",
|
||||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||||
@ApiResponse(responseCode = "403",
|
@ApiResponse(responseCode = "403",
|
||||||
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " +
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
|
|||||||
|
|
||||||
import static org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility.sanitizeActionSortParam;
|
import static org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility.sanitizeActionSortParam;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.audit.AuditLog;
|
import org.eclipse.hawkbit.audit.AuditLog;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||||
@@ -29,8 +31,6 @@ import org.springframework.http.ResponseEntity;
|
|||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@ConditionalOnProperty(name = "hawkbit.rest.MgmtActionResource.enabled", matchIfMissing = true)
|
@ConditionalOnProperty(name = "hawkbit.rest.MgmtActionResource.enabled", matchIfMissing = true)
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
package org.eclipse.hawkbit.mgmt.rest.resource;
|
package org.eclipse.hawkbit.mgmt.rest.resource;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.audit.AuditLog;
|
import org.eclipse.hawkbit.audit.AuditLog;
|
||||||
|
import org.eclipse.hawkbit.context.AccessContext;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.auth.MgmtUserInfo;
|
import org.eclipse.hawkbit.mgmt.json.model.auth.MgmtUserInfo;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtBasicAuthRestApi;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtBasicAuthRestApi;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
@@ -25,18 +25,12 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
public class MgmtBasicAuthResource implements MgmtBasicAuthRestApi {
|
public class MgmtBasicAuthResource implements MgmtBasicAuthRestApi {
|
||||||
|
|
||||||
private final TenantAware tenantAware;
|
|
||||||
|
|
||||||
public MgmtBasicAuthResource(final TenantAware tenantAware) {
|
|
||||||
this.tenantAware = tenantAware;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@AuditLog(entity = "BasicAuth", type = AuditLog.Type.READ, description = "Validate Basic Auth")
|
@AuditLog(entity = "BasicAuth", type = AuditLog.Type.READ, description = "Validate Basic Auth")
|
||||||
public ResponseEntity<MgmtUserInfo> validateBasicAuth() {
|
public ResponseEntity<MgmtUserInfo> validateBasicAuth() {
|
||||||
final MgmtUserInfo userInfo = new MgmtUserInfo();
|
final MgmtUserInfo userInfo = new MgmtUserInfo();
|
||||||
userInfo.setTenant(tenantAware.getCurrentTenant());
|
userInfo.setTenant(AccessContext.tenant());
|
||||||
userInfo.setUsername(tenantAware.getCurrentUsername());
|
userInfo.setUsername(AccessContext.actor());
|
||||||
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
if (authentication != null) {
|
if (authentication != null) {
|
||||||
userInfo.setPermissions(authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).toArray(String[]::new));
|
userInfo.setPermissions(authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).toArray(String[]::new));
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
|||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
|
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
||||||
@@ -65,8 +65,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
|||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@@ -89,7 +87,6 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
|||||||
private final DeploymentManagement deployManagement;
|
private final DeploymentManagement deployManagement;
|
||||||
private final SystemManagement systemManagement;
|
private final SystemManagement systemManagement;
|
||||||
private final MgmtDistributionSetMapper mgmtDistributionSetMapper;
|
private final MgmtDistributionSetMapper mgmtDistributionSetMapper;
|
||||||
private final TenantConfigHelper tenantConfigHelper;
|
|
||||||
|
|
||||||
@SuppressWarnings("java:S107")
|
@SuppressWarnings("java:S107")
|
||||||
MgmtDistributionSetResource(
|
MgmtDistributionSetResource(
|
||||||
@@ -99,9 +96,9 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
|||||||
final DistributionSetInvalidationManagement distributionSetInvalidationManagement,
|
final DistributionSetInvalidationManagement distributionSetInvalidationManagement,
|
||||||
final TargetManagement<? extends Target> targetManagement,
|
final TargetManagement<? extends Target> targetManagement,
|
||||||
final TargetFilterQueryManagement<? extends TargetFilterQuery> targetFilterQueryManagement,
|
final TargetFilterQueryManagement<? extends TargetFilterQuery> targetFilterQueryManagement,
|
||||||
final DeploymentManagement deployManagement, final TenantConfigurationManagement tenantConfigurationManagement,
|
final DeploymentManagement deployManagement,
|
||||||
final MgmtDistributionSetMapper mgmtDistributionSetMapper,
|
final MgmtDistributionSetMapper mgmtDistributionSetMapper,
|
||||||
final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext) {
|
final SystemManagement systemManagement) {
|
||||||
this.softwareModuleManagement = softwareModuleManagement;
|
this.softwareModuleManagement = softwareModuleManagement;
|
||||||
this.distributionSetManagement = distributionSetManagement;
|
this.distributionSetManagement = distributionSetManagement;
|
||||||
this.distributionSetTypeManagement = distributionSetTypeManagement;
|
this.distributionSetTypeManagement = distributionSetTypeManagement;
|
||||||
@@ -109,7 +106,6 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
|||||||
this.targetManagement = targetManagement;
|
this.targetManagement = targetManagement;
|
||||||
this.targetFilterQueryManagement = targetFilterQueryManagement;
|
this.targetFilterQueryManagement = targetFilterQueryManagement;
|
||||||
this.deployManagement = deployManagement;
|
this.deployManagement = deployManagement;
|
||||||
this.tenantConfigHelper = TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement);
|
|
||||||
this.mgmtDistributionSetMapper = mgmtDistributionSetMapper;
|
this.mgmtDistributionSetMapper = mgmtDistributionSetMapper;
|
||||||
this.systemManagement = systemManagement;
|
this.systemManagement = systemManagement;
|
||||||
}
|
}
|
||||||
@@ -209,7 +205,7 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ResponseEntity.ok(new PagedList<>(
|
return ResponseEntity.ok(new PagedList<>(
|
||||||
MgmtTargetMapper.toResponse(targetsAssignedDS.getContent(), tenantConfigHelper), targetsAssignedDS.getTotalElements()));
|
MgmtTargetMapper.toResponse(targetsAssignedDS.getContent()), targetsAssignedDS.getTotalElements()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -227,7 +223,7 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ResponseEntity.ok(new PagedList<>(
|
return ResponseEntity.ok(new PagedList<>(
|
||||||
MgmtTargetMapper.toResponse(targetsInstalledDS.getContent(), tenantConfigHelper), targetsInstalledDS.getTotalElements()));
|
MgmtTargetMapper.toResponse(targetsInstalledDS.getContent()), targetsInstalledDS.getTotalElements()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -239,7 +235,8 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
|||||||
.findByAutoAssignDSAndRsql(distributionSetId, rsqlParam, pageable);
|
.findByAutoAssignDSAndRsql(distributionSetId, rsqlParam, pageable);
|
||||||
|
|
||||||
return ResponseEntity.ok(new PagedList<>(
|
return ResponseEntity.ok(new PagedList<>(
|
||||||
MgmtTargetFilterQueryMapper.toResponse(targetFilterQueries.getContent(), tenantConfigHelper.isConfirmationFlowEnabled(), false),
|
MgmtTargetFilterQueryMapper.toResponse(
|
||||||
|
targetFilterQueries.getContent(), TenantConfigHelper.isUserConfirmationFlowEnabled(), false),
|
||||||
targetFilterQueries.getTotalElements()));
|
targetFilterQueries.getTotalElements()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,13 +253,13 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
|||||||
|
|
||||||
final List<DeploymentRequest> deploymentRequests = assignments.stream().map(dsAssignment -> {
|
final List<DeploymentRequest> deploymentRequests = assignments.stream().map(dsAssignment -> {
|
||||||
final boolean isConfirmationRequired = dsAssignment.getConfirmationRequired() == null
|
final boolean isConfirmationRequired = dsAssignment.getConfirmationRequired() == null
|
||||||
? tenantConfigHelper.isConfirmationFlowEnabled()
|
? TenantConfigHelper.isUserConfirmationFlowEnabled()
|
||||||
: dsAssignment.getConfirmationRequired();
|
: dsAssignment.getConfirmationRequired();
|
||||||
return MgmtDeploymentRequestMapper.createAssignmentRequestBuilder(dsAssignment, distributionSetId)
|
return MgmtDeploymentRequestMapper.createAssignmentRequestBuilder(dsAssignment, distributionSetId)
|
||||||
.confirmationRequired(isConfirmationRequired).build();
|
.confirmationRequired(isConfirmationRequired).build();
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
final List<DistributionSetAssignmentResult> assignmentResults = deployManagement.assignDistributionSets(deploymentRequests);
|
final List<DistributionSetAssignmentResult> assignmentResults = deployManagement.assignDistributionSets(deploymentRequests, null);
|
||||||
return ResponseEntity.ok(mgmtDistributionSetMapper.toResponse(assignmentResults));
|
return ResponseEntity.ok(mgmtDistributionSetMapper.toResponse(assignmentResults));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ public class MgmtOpenApiConfiguration {
|
|||||||
|
|
||||||
private static ServerVariable tenantSeverVariable() {
|
private static ServerVariable tenantSeverVariable() {
|
||||||
final ServerVariable tenantServerVariable = new ServerVariable();
|
final ServerVariable tenantServerVariable = new ServerVariable();
|
||||||
tenantServerVariable.setDescription("Tenant identifier");
|
tenantServerVariable.setDescription("AccessContext identifier");
|
||||||
tenantServerVariable.setDefault("DEFAULT");
|
tenantServerVariable.setDefault("DEFAULT");
|
||||||
return tenantServerVariable;
|
return tenantServerVariable;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ import org.eclipse.hawkbit.repository.RolloutManagement;
|
|||||||
import org.eclipse.hawkbit.repository.RolloutManagement.Create;
|
import org.eclipse.hawkbit.repository.RolloutManagement.Create;
|
||||||
import org.eclipse.hawkbit.repository.RolloutManagement.GroupCreate;
|
import org.eclipse.hawkbit.repository.RolloutManagement.GroupCreate;
|
||||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||||
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||||
@@ -47,8 +47,6 @@ import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
|
|||||||
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
|
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@@ -66,19 +64,15 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
|
|||||||
private final RolloutGroupManagement rolloutGroupManagement;
|
private final RolloutGroupManagement rolloutGroupManagement;
|
||||||
private final DistributionSetManagement<? extends DistributionSet> distributionSetManagement;
|
private final DistributionSetManagement<? extends DistributionSet> distributionSetManagement;
|
||||||
private final TargetFilterQueryManagement<? extends TargetFilterQuery> targetFilterQueryManagement;
|
private final TargetFilterQueryManagement<? extends TargetFilterQuery> targetFilterQueryManagement;
|
||||||
private final TenantConfigHelper tenantConfigHelper;
|
|
||||||
|
|
||||||
MgmtRolloutResource(
|
MgmtRolloutResource(
|
||||||
final RolloutManagement rolloutManagement, final RolloutGroupManagement rolloutGroupManagement,
|
final RolloutManagement rolloutManagement, final RolloutGroupManagement rolloutGroupManagement,
|
||||||
final DistributionSetManagement<? extends DistributionSet> distributionSetManagement,
|
final DistributionSetManagement<? extends DistributionSet> distributionSetManagement,
|
||||||
final TargetFilterQueryManagement<? extends TargetFilterQuery> targetFilterQueryManagement,
|
final TargetFilterQueryManagement<? extends TargetFilterQuery> targetFilterQueryManagement) {
|
||||||
final SystemSecurityContext systemSecurityContext,
|
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement) {
|
|
||||||
this.rolloutManagement = rolloutManagement;
|
this.rolloutManagement = rolloutManagement;
|
||||||
this.rolloutGroupManagement = rolloutGroupManagement;
|
this.rolloutGroupManagement = rolloutGroupManagement;
|
||||||
this.distributionSetManagement = distributionSetManagement;
|
this.distributionSetManagement = distributionSetManagement;
|
||||||
this.targetFilterQueryManagement = targetFilterQueryManagement;
|
this.targetFilterQueryManagement = targetFilterQueryManagement;
|
||||||
this.tenantConfigHelper = TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -121,7 +115,7 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
|
|||||||
final DistributionSet distributionSet = distributionSetManagement.getValidAndComplete(rolloutRequestBody.getDistributionSetId());
|
final DistributionSet distributionSet = distributionSetManagement.getValidAndComplete(rolloutRequestBody.getDistributionSetId());
|
||||||
final RolloutGroupConditions rolloutGroupConditions = MgmtRolloutMapper.fromRequest(rolloutRequestBody, true);
|
final RolloutGroupConditions rolloutGroupConditions = MgmtRolloutMapper.fromRequest(rolloutRequestBody, true);
|
||||||
final Create create = MgmtRolloutMapper.fromRequest(rolloutRequestBody, distributionSet);
|
final Create create = MgmtRolloutMapper.fromRequest(rolloutRequestBody, distributionSet);
|
||||||
final boolean confirmationFlowActive = tenantConfigHelper.isConfirmationFlowEnabled();
|
final boolean confirmationFlowActive = TenantConfigHelper.isUserConfirmationFlowEnabled();
|
||||||
|
|
||||||
final Rollout rollout;
|
final Rollout rollout;
|
||||||
if (rolloutRequestBody.getGroups() != null) {
|
if (rolloutRequestBody.getGroups() != null) {
|
||||||
@@ -226,7 +220,7 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final List<MgmtRolloutGroupResponseBody> rest = MgmtRolloutMapper.toResponseRolloutGroup(
|
final List<MgmtRolloutGroupResponseBody> rest = MgmtRolloutMapper.toResponseRolloutGroup(
|
||||||
rolloutGroups.getContent(), tenantConfigHelper.isConfirmationFlowEnabled(), isFullMode);
|
rolloutGroups.getContent(), TenantConfigHelper.isUserConfirmationFlowEnabled(), isFullMode);
|
||||||
return ResponseEntity.ok(new PagedList<>(rest, rolloutGroups.getTotalElements()));
|
return ResponseEntity.ok(new PagedList<>(rest, rolloutGroups.getTotalElements()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +234,7 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ResponseEntity.ok(MgmtRolloutMapper.toResponseRolloutGroup(
|
return ResponseEntity.ok(MgmtRolloutMapper.toResponseRolloutGroup(
|
||||||
rolloutGroup, true, tenantConfigHelper.isConfirmationFlowEnabled()));
|
rolloutGroup, true, TenantConfigHelper.isUserConfirmationFlowEnabled()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -255,7 +249,7 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
|
|||||||
} else {
|
} else {
|
||||||
rolloutGroupTargets = this.rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(groupId, rsqlParam, pageable);
|
rolloutGroupTargets = this.rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(groupId, rsqlParam, pageable);
|
||||||
}
|
}
|
||||||
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(rolloutGroupTargets.getContent(), tenantConfigHelper);
|
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(rolloutGroupTargets.getContent());
|
||||||
return ResponseEntity.ok(new PagedList<>(rest, rolloutGroupTargets.getTotalElements()));
|
return ResponseEntity.ok(new PagedList<>(rest, rolloutGroupTargets.getTotalElements()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import java.util.Optional;
|
|||||||
import jakarta.validation.ValidationException;
|
import jakarta.validation.ValidationException;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.eclipse.hawkbit.artifact.model.ArtifactHashes;
|
||||||
|
import org.eclipse.hawkbit.artifact.urlresolver.ArtifactUrlResolver;
|
||||||
import org.eclipse.hawkbit.audit.AuditLog;
|
import org.eclipse.hawkbit.audit.AuditLog;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
|
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
|
||||||
@@ -38,8 +40,6 @@ import org.eclipse.hawkbit.repository.ArtifactManagement;
|
|||||||
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
||||||
import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement;
|
import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement;
|
||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
import org.eclipse.hawkbit.artifact.model.ArtifactHashes;
|
|
||||||
import org.eclipse.hawkbit.artifact.urlresolver.ArtifactUrlResolver;
|
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||||
import org.eclipse.hawkbit.repository.model.ArtifactUpload;
|
import org.eclipse.hawkbit.repository.model.ArtifactUpload;
|
||||||
|
|||||||
@@ -27,12 +27,10 @@ import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtTargetFilterQueryMapper
|
|||||||
import org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility;
|
import org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility;
|
||||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement.AutoAssignDistributionSetUpdate;
|
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement.AutoAssignDistributionSetUpdate;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@@ -47,14 +45,9 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestApi {
|
public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestApi {
|
||||||
|
|
||||||
private final TargetFilterQueryManagement<? extends TargetFilterQuery> filterManagement;
|
private final TargetFilterQueryManagement<? extends TargetFilterQuery> filterManagement;
|
||||||
private final TenantConfigHelper tenantConfigHelper;
|
|
||||||
|
|
||||||
MgmtTargetFilterQueryResource(
|
MgmtTargetFilterQueryResource(final TargetFilterQueryManagement<? extends TargetFilterQuery> filterManagement) {
|
||||||
final TargetFilterQueryManagement<? extends TargetFilterQuery> filterManagement,
|
|
||||||
final SystemSecurityContext systemSecurityContext,
|
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement) {
|
|
||||||
this.filterManagement = filterManagement;
|
this.filterManagement = filterManagement;
|
||||||
this.tenantConfigHelper = TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -62,7 +55,7 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
|
|||||||
final TargetFilterQuery findTarget = findFilterWithExceptionIfNotFound(filterId);
|
final TargetFilterQuery findTarget = findFilterWithExceptionIfNotFound(filterId);
|
||||||
// to single response include poll status
|
// to single response include poll status
|
||||||
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(findTarget,
|
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(findTarget,
|
||||||
tenantConfigHelper.isConfirmationFlowEnabled(), true);
|
TenantConfigHelper.isUserConfirmationFlowEnabled(), true);
|
||||||
MgmtTargetFilterQueryMapper.addLinks(response);
|
MgmtTargetFilterQueryMapper.addLinks(response);
|
||||||
|
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
@@ -82,8 +75,8 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
|
|||||||
|
|
||||||
final boolean isRepresentationFull = parseRepresentationMode(representationModeParam) == MgmtRepresentationMode.FULL;
|
final boolean isRepresentationFull = parseRepresentationMode(representationModeParam) == MgmtRepresentationMode.FULL;
|
||||||
|
|
||||||
final List<MgmtTargetFilterQuery> rest = MgmtTargetFilterQueryMapper
|
final List<MgmtTargetFilterQuery> rest = MgmtTargetFilterQueryMapper.toResponse(
|
||||||
.toResponse(findTargetFiltersAll.getContent(), tenantConfigHelper.isConfirmationFlowEnabled(), isRepresentationFull);
|
findTargetFiltersAll.getContent(), TenantConfigHelper.isUserConfirmationFlowEnabled(), isRepresentationFull);
|
||||||
return ResponseEntity.ok(new PagedList<>(rest, filterManagement.count()));
|
return ResponseEntity.ok(new PagedList<>(rest, filterManagement.count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +85,7 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
|
|||||||
final TargetFilterQuery createdTarget = filterManagement.create(MgmtTargetFilterQueryMapper.fromRequest(filter));
|
final TargetFilterQuery createdTarget = filterManagement.create(MgmtTargetFilterQueryMapper.fromRequest(filter));
|
||||||
|
|
||||||
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(
|
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(
|
||||||
createdTarget, tenantConfigHelper.isConfirmationFlowEnabled(), false);
|
createdTarget, TenantConfigHelper.isUserConfirmationFlowEnabled(), false);
|
||||||
MgmtTargetFilterQueryMapper.addLinks(response);
|
MgmtTargetFilterQueryMapper.addLinks(response);
|
||||||
|
|
||||||
return new ResponseEntity<>(response, HttpStatus.CREATED);
|
return new ResponseEntity<>(response, HttpStatus.CREATED);
|
||||||
@@ -108,7 +101,7 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
|
|||||||
.build());
|
.build());
|
||||||
|
|
||||||
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(updateFilter,
|
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(updateFilter,
|
||||||
tenantConfigHelper.isConfirmationFlowEnabled(), false);
|
TenantConfigHelper.isUserConfirmationFlowEnabled(), false);
|
||||||
MgmtTargetFilterQueryMapper.addLinks(response);
|
MgmtTargetFilterQueryMapper.addLinks(response);
|
||||||
|
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
@@ -141,7 +134,7 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
|
|||||||
public ResponseEntity<MgmtTargetFilterQuery> postAssignedDistributionSet(
|
public ResponseEntity<MgmtTargetFilterQuery> postAssignedDistributionSet(
|
||||||
final Long filterId, final MgmtDistributionSetAutoAssignment autoAssignRequest) {
|
final Long filterId, final MgmtDistributionSetAutoAssignment autoAssignRequest) {
|
||||||
final boolean confirmationRequired = autoAssignRequest.getConfirmationRequired() == null
|
final boolean confirmationRequired = autoAssignRequest.getConfirmationRequired() == null
|
||||||
? tenantConfigHelper.isConfirmationFlowEnabled()
|
? TenantConfigHelper.isUserConfirmationFlowEnabled()
|
||||||
: autoAssignRequest.getConfirmationRequired();
|
: autoAssignRequest.getConfirmationRequired();
|
||||||
|
|
||||||
final AutoAssignDistributionSetUpdate update = MgmtTargetFilterQueryMapper
|
final AutoAssignDistributionSetUpdate update = MgmtTargetFilterQueryMapper
|
||||||
@@ -150,7 +143,7 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
|
|||||||
final TargetFilterQuery updateFilter = filterManagement.updateAutoAssignDS(update);
|
final TargetFilterQuery updateFilter = filterManagement.updateAutoAssignDS(update);
|
||||||
|
|
||||||
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(updateFilter,
|
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(updateFilter,
|
||||||
tenantConfigHelper.isConfirmationFlowEnabled(), false);
|
TenantConfigHelper.isUserConfirmationFlowEnabled(), false);
|
||||||
MgmtTargetFilterQueryMapper.addLinks(response);
|
MgmtTargetFilterQueryMapper.addLinks(response);
|
||||||
|
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.mgmt.rest.resource;
|
package org.eclipse.hawkbit.mgmt.rest.resource;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility.sanitizeTargetSortParam;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
|
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
|
||||||
@@ -16,31 +20,21 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetGroupRestApi;
|
|||||||
import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtTargetMapper;
|
import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtTargetMapper;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility;
|
import org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility;
|
||||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility.sanitizeTargetSortParam;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
public class MgmtTargetGroupResource implements MgmtTargetGroupRestApi {
|
public class MgmtTargetGroupResource implements MgmtTargetGroupRestApi {
|
||||||
|
|
||||||
private final TargetManagement<? extends Target> targetManagement;
|
private final TargetManagement<? extends Target> targetManagement;
|
||||||
private final TenantConfigHelper tenantConfigHelper;
|
|
||||||
|
|
||||||
public MgmtTargetGroupResource(
|
public MgmtTargetGroupResource(
|
||||||
final TargetManagement <? extends Target>targetManagement,
|
final TargetManagement <? extends Target>targetManagement) {
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement, final SystemSecurityContext systemSecurityContext) {
|
|
||||||
this.targetManagement = targetManagement;
|
this.targetManagement = targetManagement;
|
||||||
this.tenantConfigHelper = TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -50,7 +44,7 @@ public class MgmtTargetGroupResource implements MgmtTargetGroupRestApi {
|
|||||||
|
|
||||||
final Page<Target> targets = targetManagement.findTargetsByGroup(group, false, pageable);
|
final Page<Target> targets = targetManagement.findTargetsByGroup(group, false, pageable);
|
||||||
|
|
||||||
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(targets.getContent(), tenantConfigHelper);
|
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(targets.getContent());
|
||||||
return ResponseEntity.ok(new PagedList<>(rest, targets.getTotalElements()));
|
return ResponseEntity.ok(new PagedList<>(rest, targets.getTotalElements()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +55,7 @@ public class MgmtTargetGroupResource implements MgmtTargetGroupRestApi {
|
|||||||
|
|
||||||
final Page<Target> targets = targetManagement.findTargetsByGroup(groupFilter, subgroups, pageable);
|
final Page<Target> targets = targetManagement.findTargetsByGroup(groupFilter, subgroups, pageable);
|
||||||
|
|
||||||
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(targets.getContent(), tenantConfigHelper);
|
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(targets.getContent());
|
||||||
return ResponseEntity.ok(new PagedList<>(rest, targets.getTotalElements()));
|
return ResponseEntity.ok(new PagedList<>(rest, targets.getTotalElements()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,9 +56,9 @@ import org.eclipse.hawkbit.repository.ConfirmationManagement;
|
|||||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||||
import org.eclipse.hawkbit.repository.TargetTypeManagement;
|
import org.eclipse.hawkbit.repository.TargetTypeManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
import org.eclipse.hawkbit.repository.exception.InvalidConfirmationFeedbackException;
|
import org.eclipse.hawkbit.repository.exception.InvalidConfirmationFeedbackException;
|
||||||
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
|
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
|
||||||
@@ -66,8 +66,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
|||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
@@ -91,27 +89,24 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
|
|||||||
private final DeploymentManagement deploymentManagement;
|
private final DeploymentManagement deploymentManagement;
|
||||||
private final MgmtTargetMapper mgmtTargetMapper;
|
private final MgmtTargetMapper mgmtTargetMapper;
|
||||||
private final MgmtDistributionSetMapper mgmtDistributionSetMapper;
|
private final MgmtDistributionSetMapper mgmtDistributionSetMapper;
|
||||||
private final TenantConfigHelper tenantConfigHelper;
|
|
||||||
|
|
||||||
MgmtTargetResource(
|
MgmtTargetResource(
|
||||||
final TargetManagement<? extends Target> targetManagement, final TargetTypeManagement<? extends TargetType> targetTypeManagement,
|
final TargetManagement<? extends Target> targetManagement, final TargetTypeManagement<? extends TargetType> targetTypeManagement,
|
||||||
final DeploymentManagement deploymentManagement, final ConfirmationManagement confirmationManagement,
|
final DeploymentManagement deploymentManagement, final ConfirmationManagement confirmationManagement,
|
||||||
final MgmtTargetMapper mgmtTargetMapper, final MgmtDistributionSetMapper mgmtDistributionSetMapper,
|
final MgmtTargetMapper mgmtTargetMapper, final MgmtDistributionSetMapper mgmtDistributionSetMapper) {
|
||||||
final SystemSecurityContext systemSecurityContext, final TenantConfigurationManagement tenantConfigurationManagement) {
|
|
||||||
this.targetManagement = targetManagement;
|
this.targetManagement = targetManagement;
|
||||||
this.targetTypeManagement = targetTypeManagement;
|
this.targetTypeManagement = targetTypeManagement;
|
||||||
this.deploymentManagement = deploymentManagement;
|
this.deploymentManagement = deploymentManagement;
|
||||||
this.confirmationManagement = confirmationManagement;
|
this.confirmationManagement = confirmationManagement;
|
||||||
this.mgmtTargetMapper = mgmtTargetMapper;
|
this.mgmtTargetMapper = mgmtTargetMapper;
|
||||||
this.mgmtDistributionSetMapper = mgmtDistributionSetMapper;
|
this.mgmtDistributionSetMapper = mgmtDistributionSetMapper;
|
||||||
this.tenantConfigHelper = TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<MgmtTarget> getTarget(final String targetId) {
|
public ResponseEntity<MgmtTarget> getTarget(final String targetId) {
|
||||||
final Target findTarget = targetManagement.getByControllerId(targetId);
|
final Target findTarget = targetManagement.getByControllerId(targetId);
|
||||||
// to single response include poll status
|
// to single response include poll status
|
||||||
final MgmtTarget response = MgmtTargetMapper.toResponse(findTarget, tenantConfigHelper, null);
|
final MgmtTarget response = MgmtTargetMapper.toResponse(findTarget, null);
|
||||||
MgmtTargetMapper.addTargetLinks(response);
|
MgmtTargetMapper.addTargetLinks(response);
|
||||||
|
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
@@ -128,7 +123,7 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
|
|||||||
findTargetsAll = targetManagement.findAll(pageable);
|
findTargetsAll = targetManagement.findAll(pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(findTargetsAll.getContent(), tenantConfigHelper);
|
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(findTargetsAll.getContent());
|
||||||
return ResponseEntity.ok(new PagedList<>(rest, findTargetsAll.getTotalElements()));
|
return ResponseEntity.ok(new PagedList<>(rest, findTargetsAll.getTotalElements()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +132,7 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
|
|||||||
log.debug("creating {} targets", targets.size());
|
log.debug("creating {} targets", targets.size());
|
||||||
final Collection<? extends Target> createdTargets = this.targetManagement.create(mgmtTargetMapper.fromRequest(targets));
|
final Collection<? extends Target> createdTargets = this.targetManagement.create(mgmtTargetMapper.fromRequest(targets));
|
||||||
log.debug("{} targets created, return status {}", targets.size(), HttpStatus.CREATED);
|
log.debug("{} targets created, return status {}", targets.size(), HttpStatus.CREATED);
|
||||||
return new ResponseEntity<>(MgmtTargetMapper.toResponse(createdTargets, tenantConfigHelper), HttpStatus.CREATED);
|
return new ResponseEntity<>(MgmtTargetMapper.toResponse(createdTargets), HttpStatus.CREATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -166,7 +161,7 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
|
|||||||
.requestControllerAttributes(targetRest.getRequestAttributes())
|
.requestControllerAttributes(targetRest.getRequestAttributes())
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
final MgmtTarget response = MgmtTargetMapper.toResponse(updateTarget, tenantConfigHelper, null);
|
final MgmtTarget response = MgmtTargetMapper.toResponse(updateTarget, null);
|
||||||
MgmtTargetMapper.addTargetLinks(response);
|
MgmtTargetMapper.addTargetLinks(response);
|
||||||
|
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
@@ -399,14 +394,13 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
|
|||||||
|
|
||||||
final List<DeploymentRequest> deploymentRequests = dsAssignments.stream().map(dsAssignment -> {
|
final List<DeploymentRequest> deploymentRequests = dsAssignments.stream().map(dsAssignment -> {
|
||||||
final boolean isConfirmationRequired = dsAssignment.getConfirmationRequired() == null
|
final boolean isConfirmationRequired = dsAssignment.getConfirmationRequired() == null
|
||||||
? tenantConfigHelper.isConfirmationFlowEnabled()
|
? TenantConfigHelper.isUserConfirmationFlowEnabled()
|
||||||
: dsAssignment.getConfirmationRequired();
|
: dsAssignment.getConfirmationRequired();
|
||||||
return MgmtDeploymentRequestMapper.createAssignmentRequestBuilder(dsAssignment, targetId)
|
return MgmtDeploymentRequestMapper.createAssignmentRequestBuilder(dsAssignment, targetId)
|
||||||
.confirmationRequired(isConfirmationRequired).build();
|
.confirmationRequired(isConfirmationRequired).build();
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
final List<DistributionSetAssignmentResult> assignmentResults = deploymentManagement
|
final List<DistributionSetAssignmentResult> assignmentResults = deploymentManagement.assignDistributionSets(deploymentRequests, null);
|
||||||
.assignDistributionSets(deploymentRequests);
|
|
||||||
return ResponseEntity.ok(mgmtDistributionSetMapper.toResponse(assignmentResults));
|
return ResponseEntity.ok(mgmtDistributionSetMapper.toResponse(assignmentResults));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,6 +480,6 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private <T, R> R getNullIfEmpty(final T object, final Function<T, R> extractMethod) {
|
private <T, R> R getNullIfEmpty(final T object, final Function<T, R> extractMethod) {
|
||||||
return object == null ? null : extractMethod.apply(object);
|
return ObjectUtils.isEmpty(object) ? null : extractMethod.apply(object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,12 +27,9 @@ import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtTargetMapper;
|
|||||||
import org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility;
|
import org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility;
|
||||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||||
import org.eclipse.hawkbit.repository.TargetTagManagement;
|
import org.eclipse.hawkbit.repository.TargetTagManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
|
||||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@@ -48,14 +45,11 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
|
|||||||
|
|
||||||
private final TargetTagManagement<? extends TargetTag> tagManagement;
|
private final TargetTagManagement<? extends TargetTag> tagManagement;
|
||||||
private final TargetManagement<? extends Target> targetManagement;
|
private final TargetManagement<? extends Target> targetManagement;
|
||||||
private final TenantConfigHelper tenantConfigHelper;
|
|
||||||
|
|
||||||
MgmtTargetTagResource(
|
MgmtTargetTagResource(
|
||||||
final TargetTagManagement<? extends TargetTag> tagManagement, final TargetManagement<? extends Target> targetManagement,
|
final TargetTagManagement<? extends TargetTag> tagManagement, final TargetManagement<? extends Target> targetManagement) {
|
||||||
final SystemSecurityContext securityContext, final TenantConfigurationManagement configurationManagement) {
|
|
||||||
this.tagManagement = tagManagement;
|
this.tagManagement = tagManagement;
|
||||||
this.targetManagement = targetManagement;
|
this.targetManagement = targetManagement;
|
||||||
tenantConfigHelper = TenantConfigHelper.usingContext(securityContext, configurationManagement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -129,7 +123,7 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
|
|||||||
findTargetsAll = targetManagement.findByRsqlAndTag(rsqlParam, targetTagId, pageable);
|
findTargetsAll = targetManagement.findByRsqlAndTag(rsqlParam, targetTagId, pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(findTargetsAll.getContent(), tenantConfigHelper);
|
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(findTargetsAll.getContent());
|
||||||
return ResponseEntity.ok(new PagedList<>(rest, findTargetsAll.getTotalElements()));
|
return ResponseEntity.ok(new PagedList<>(rest, findTargetsAll.getTotalElements()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import org.springframework.data.domain.Page;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationV
|
|||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTenantManagementRestApi;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTenantManagementRestApi;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtTenantManagementMapper;
|
import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtTenantManagementMapper;
|
||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
|
||||||
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
|
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
|
||||||
import org.eclipse.hawkbit.repository.exception.TenantConfigurationValidatorException;
|
import org.eclipse.hawkbit.repository.exception.TenantConfigurationValidatorException;
|
||||||
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@@ -38,22 +38,19 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi {
|
public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi {
|
||||||
|
|
||||||
private final TenantConfigurationManagement tenantConfigurationManagement;
|
|
||||||
private final TenantConfigurationProperties tenantConfigurationProperties;
|
private final TenantConfigurationProperties tenantConfigurationProperties;
|
||||||
private final SystemManagement systemManagement;
|
private final SystemManagement systemManagement;
|
||||||
|
|
||||||
MgmtTenantManagementResource(
|
MgmtTenantManagementResource(
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement,
|
|
||||||
final TenantConfigurationProperties tenantConfigurationProperties,
|
final TenantConfigurationProperties tenantConfigurationProperties,
|
||||||
final SystemManagement systemManagement) {
|
final SystemManagement systemManagement) {
|
||||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
|
||||||
this.tenantConfigurationProperties = tenantConfigurationProperties;
|
this.tenantConfigurationProperties = tenantConfigurationProperties;
|
||||||
this.systemManagement = systemManagement;
|
this.systemManagement = systemManagement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Map<String, MgmtSystemTenantConfigurationValue>> getTenantConfiguration() {
|
public ResponseEntity<Map<String, MgmtSystemTenantConfigurationValue>> getTenantConfiguration() {
|
||||||
// Load and Construct default Tenant Configuration
|
// Load and Construct default AccessContext Configuration
|
||||||
final Map<String, MgmtSystemTenantConfigurationValue> tenantConfigurationValueMap = new HashMap<>();
|
final Map<String, MgmtSystemTenantConfigurationValue> tenantConfigurationValueMap = new HashMap<>();
|
||||||
tenantConfigurationProperties.getConfigurationKeys().forEach(key -> {
|
tenantConfigurationProperties.getConfigurationKeys().forEach(key -> {
|
||||||
try {
|
try {
|
||||||
@@ -74,14 +71,14 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@AuditLog(entity = "TenantConfiguration", type = AuditLog.Type.DELETE, description = "Delete Tenant Configuration Value")
|
@AuditLog(entity = "TenantConfiguration", type = AuditLog.Type.DELETE, description = "Delete AccessContext Configuration Value")
|
||||||
public ResponseEntity<Void> deleteTenantConfigurationValue(final String keyName) {
|
public ResponseEntity<Void> deleteTenantConfigurationValue(final String keyName) {
|
||||||
//Default DistributionSet Type cannot be deleted as is part of TenantMetadata
|
// Default DistributionSet Type cannot be deleted as is part of TenantMetadata
|
||||||
if (isDefaultDistributionSetTypeKey(keyName)) {
|
if (isDefaultDistributionSetTypeKey(keyName)) {
|
||||||
return ResponseEntity.badRequest().build();
|
return ResponseEntity.badRequest().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
tenantConfigurationManagement.deleteConfiguration(keyName);
|
TenantConfigHelper.getTenantConfigurationManagement().deleteConfiguration(keyName);
|
||||||
|
|
||||||
log.debug("{} config value deleted, return status {}", keyName, HttpStatus.OK);
|
log.debug("{} config value deleted, return status {}", keyName, HttpStatus.OK);
|
||||||
return ResponseEntity.noContent().build();
|
return ResponseEntity.noContent().build();
|
||||||
@@ -93,7 +90,7 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@AuditLog(entity = "TenantConfiguration", type = AuditLog.Type.UPDATE, description = "Update Tenant Configuration Value")
|
@AuditLog(entity = "TenantConfiguration", type = AuditLog.Type.UPDATE, description = "Update AccessContext Configuration Value")
|
||||||
public ResponseEntity<MgmtSystemTenantConfigurationValue> updateTenantConfigurationValue(
|
public ResponseEntity<MgmtSystemTenantConfigurationValue> updateTenantConfigurationValue(
|
||||||
final String keyName, final MgmtSystemTenantConfigurationValueRequest configurationValueRest) {
|
final String keyName, final MgmtSystemTenantConfigurationValueRequest configurationValueRest) {
|
||||||
Serializable configurationValue = configurationValueRest.getValue();
|
Serializable configurationValue = configurationValueRest.getValue();
|
||||||
@@ -101,7 +98,8 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
|
|||||||
if (isDefaultDistributionSetTypeKey(keyName)) {
|
if (isDefaultDistributionSetTypeKey(keyName)) {
|
||||||
responseUpdatedValue = updateDefaultDsType(configurationValue);
|
responseUpdatedValue = updateDefaultDsType(configurationValue);
|
||||||
} else {
|
} else {
|
||||||
final TenantConfigurationValue<? extends Serializable> updatedTenantConfigurationValue = tenantConfigurationManagement
|
final TenantConfigurationValue<? extends Serializable> updatedTenantConfigurationValue = TenantConfigHelper
|
||||||
|
.getTenantConfigurationManagement()
|
||||||
.addOrUpdateConfiguration(keyName, configurationValueRest.getValue());
|
.addOrUpdateConfiguration(keyName, configurationValueRest.getValue());
|
||||||
responseUpdatedValue = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(keyName, updatedTenantConfigurationValue);
|
responseUpdatedValue = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(keyName, updatedTenantConfigurationValue);
|
||||||
}
|
}
|
||||||
@@ -110,7 +108,7 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@AuditLog(entity = "TenantConfiguration", type = AuditLog.Type.UPDATE, description = "Update Tenant Configuration")
|
@AuditLog(entity = "TenantConfiguration", type = AuditLog.Type.UPDATE, description = "Update AccessContext Configuration")
|
||||||
public ResponseEntity<List<MgmtSystemTenantConfigurationValue>> updateTenantConfiguration(
|
public ResponseEntity<List<MgmtSystemTenantConfigurationValue>> updateTenantConfiguration(
|
||||||
final Map<String, Serializable> configurationValueMap) {
|
final Map<String, Serializable> configurationValueMap) {
|
||||||
final boolean containsNull = configurationValueMap.keySet().stream().anyMatch(Objects::isNull);
|
final boolean containsNull = configurationValueMap.keySet().stream().anyMatch(Objects::isNull);
|
||||||
@@ -130,7 +128,7 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
|
|||||||
//try update TenantConfiguration, in case of Error -> rollback TenantMetadata
|
//try update TenantConfiguration, in case of Error -> rollback TenantMetadata
|
||||||
final Map<String, TenantConfigurationValue<Serializable>> tenantConfigurationValues;
|
final Map<String, TenantConfigurationValue<Serializable>> tenantConfigurationValues;
|
||||||
try {
|
try {
|
||||||
tenantConfigurationValues = tenantConfigurationManagement.addOrUpdateConfiguration(configurationValueMap);
|
tenantConfigurationValues = TenantConfigHelper.getTenantConfigurationManagement().addOrUpdateConfiguration(configurationValueMap);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
//if DefaultDsType was updated, rollback it in case of TenantConfiguration update.
|
//if DefaultDsType was updated, rollback it in case of TenantConfiguration update.
|
||||||
if (updatedDefaultDsType != null) {
|
if (updatedDefaultDsType != null) {
|
||||||
@@ -155,13 +153,13 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private MgmtSystemTenantConfigurationValue loadTenantConfigurationValueBy(final String keyName) {
|
private MgmtSystemTenantConfigurationValue loadTenantConfigurationValueBy(final String keyName) {
|
||||||
//Check if requested key is TenantConfiguration or TenantMetadata, load it and return it as rest response
|
// Check if requested key is TenantConfiguration or TenantMetadata, load it and return it as rest response
|
||||||
final MgmtSystemTenantConfigurationValue response;
|
final MgmtSystemTenantConfigurationValue response;
|
||||||
if (isDefaultDistributionSetTypeKey(keyName)) {
|
if (isDefaultDistributionSetTypeKey(keyName)) {
|
||||||
response = MgmtTenantManagementMapper.toResponseDefaultDsType(systemManagement.getTenantMetadata().getDefaultDsType().getId());
|
response = MgmtTenantManagementMapper.toResponseDefaultDsType(systemManagement.getTenantMetadata().getDefaultDsType().getId());
|
||||||
} else {
|
} else {
|
||||||
response = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(
|
response = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(
|
||||||
keyName, tenantConfigurationManagement.getConfigurationValue(keyName));
|
keyName, TenantConfigHelper.getTenantConfigurationManagement().getConfigurationValue(keyName));
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtSoftwareModuleRestApi;
|
|||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtSoftwareModuleTypeRestApi;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtSoftwareModuleTypeRestApi;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.resource.MgmtDownloadArtifactResource;
|
import org.eclipse.hawkbit.mgmt.rest.resource.MgmtDownloadArtifactResource;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.resource.MgmtSoftwareModuleResource;
|
import org.eclipse.hawkbit.mgmt.rest.resource.MgmtSoftwareModuleResource;
|
||||||
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
|
||||||
import org.eclipse.hawkbit.repository.SoftwareModuleManagement.Create;
|
import org.eclipse.hawkbit.repository.SoftwareModuleManagement.Create;
|
||||||
import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement;
|
import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement;
|
||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
|
|||||||
@@ -39,12 +39,11 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtRolloutRestApi;
|
|||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetRestApi;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetRestApi;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTypeRestApi;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTypeRestApi;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.SortDirection;
|
import org.eclipse.hawkbit.mgmt.rest.api.SortDirection;
|
||||||
import org.eclipse.hawkbit.repository.qfields.ActionFields;
|
|
||||||
import org.eclipse.hawkbit.repository.qfields.ActionStatusFields;
|
|
||||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||||
import org.eclipse.hawkbit.repository.TargetManagement.Create;
|
import org.eclipse.hawkbit.repository.TargetManagement.Create;
|
||||||
import org.eclipse.hawkbit.repository.TargetTypeManagement;
|
import org.eclipse.hawkbit.repository.TargetTypeManagement;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
|
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||||
@@ -54,9 +53,10 @@ import org.eclipse.hawkbit.repository.model.PollStatus;
|
|||||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||||
|
import org.eclipse.hawkbit.repository.qfields.ActionFields;
|
||||||
|
import org.eclipse.hawkbit.repository.qfields.ActionStatusFields;
|
||||||
import org.eclipse.hawkbit.rest.json.model.ResponseList;
|
import org.eclipse.hawkbit.rest.json.model.ResponseList;
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.utils.IpUtil;
|
||||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
@@ -119,30 +119,16 @@ public final class MgmtTargetMapper {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static List<MgmtTarget> toResponse(final Collection<? extends Target> targets) {
|
||||||
* Create a response for targets.
|
|
||||||
*
|
|
||||||
* @param targets list of targets
|
|
||||||
* @return the response
|
|
||||||
*/
|
|
||||||
public static List<MgmtTarget> toResponse(final Collection<? extends Target> targets, final TenantConfigHelper configHelper) {
|
|
||||||
if (targets == null) {
|
if (targets == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final Function<Target, PollStatus> pollStatusResolver = configHelper.pollStatusResolver();
|
final Function<Target, PollStatus> pollStatusResolver = TenantConfigHelper.pollStatusResolver();
|
||||||
return new ResponseList<>(
|
return new ResponseList<>(targets.stream().map(target -> toResponse(target, pollStatusResolver)).toList());
|
||||||
targets.stream().map(target -> toResponse(target, configHelper, pollStatusResolver)).toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static MgmtTarget toResponse(final Target target, final Function<Target, PollStatus> pollStatusResolver) {
|
||||||
* Create a response for target.
|
|
||||||
*
|
|
||||||
* @param target the target
|
|
||||||
* @return the response
|
|
||||||
*/
|
|
||||||
public static MgmtTarget toResponse(
|
|
||||||
final Target target, final TenantConfigHelper configHelper, final Function<Target, PollStatus> pollStatusResolver) {
|
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -189,13 +175,14 @@ public final class MgmtTargetMapper {
|
|||||||
targetRest.setTargetType(target.getTargetType().getId());
|
targetRest.setTargetType(target.getTargetType().getId());
|
||||||
targetRest.setTargetTypeName(target.getTargetType().getName());
|
targetRest.setTargetTypeName(target.getTargetType().getName());
|
||||||
}
|
}
|
||||||
if (configHelper.isConfirmationFlowEnabled()) {
|
|
||||||
|
if (TenantConfigHelper.isUserConfirmationFlowEnabled()) {
|
||||||
targetRest.setAutoConfirmActive(target.getAutoConfirmationStatus() != null);
|
targetRest.setAutoConfirmActive(target.getAutoConfirmationStatus() != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
targetRest.add(linkTo(methodOn(MgmtTargetRestApi.class).getTarget(target.getControllerId())).withSelfRel().expand());
|
targetRest.add(linkTo(methodOn(MgmtTargetRestApi.class).getTarget(target.getControllerId())).withSelfRel().expand());
|
||||||
|
|
||||||
addPollStatus(target, targetRest, pollStatusResolver == null ? configHelper.pollStatusResolver() : pollStatusResolver);
|
addPollStatus(target, targetRest, pollStatusResolver == null ? TenantConfigHelper.pollStatusResolver() : pollStatusResolver);
|
||||||
|
|
||||||
return targetRest;
|
return targetRest;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ package org.eclipse.hawkbit.mgmt.rest.resource.util;
|
|||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||||
|
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
||||||
import org.eclipse.hawkbit.repository.qfields.ActionFields;
|
import org.eclipse.hawkbit.repository.qfields.ActionFields;
|
||||||
import org.eclipse.hawkbit.repository.qfields.ActionStatusFields;
|
import org.eclipse.hawkbit.repository.qfields.ActionStatusFields;
|
||||||
import org.eclipse.hawkbit.repository.qfields.DistributionSetFields;
|
import org.eclipse.hawkbit.repository.qfields.DistributionSetFields;
|
||||||
import org.eclipse.hawkbit.repository.qfields.DistributionSetTypeFields;
|
import org.eclipse.hawkbit.repository.qfields.DistributionSetTypeFields;
|
||||||
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
|
||||||
import org.eclipse.hawkbit.repository.qfields.RolloutFields;
|
import org.eclipse.hawkbit.repository.qfields.RolloutFields;
|
||||||
import org.eclipse.hawkbit.repository.qfields.RolloutGroupFields;
|
import org.eclipse.hawkbit.repository.qfields.RolloutGroupFields;
|
||||||
import org.eclipse.hawkbit.repository.qfields.SoftwareModuleFields;
|
import org.eclipse.hawkbit.repository.qfields.SoftwareModuleFields;
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ import org.eclipse.hawkbit.repository.jpa.JpaRepositoryConfiguration;
|
|||||||
import org.eclipse.hawkbit.repository.test.TestConfiguration;
|
import org.eclipse.hawkbit.repository.test.TestConfiguration;
|
||||||
import org.eclipse.hawkbit.repository.test.matcher.EventVerifier;
|
import org.eclipse.hawkbit.repository.test.matcher.EventVerifier;
|
||||||
import org.eclipse.hawkbit.repository.test.util.CleanupTestExecutionListener;
|
import org.eclipse.hawkbit.repository.test.util.CleanupTestExecutionListener;
|
||||||
import org.eclipse.hawkbit.repository.test.util.TestLoggerExtension;
|
|
||||||
import org.eclipse.hawkbit.repository.test.util.SharedSqlTestDatabaseExtension;
|
import org.eclipse.hawkbit.repository.test.util.SharedSqlTestDatabaseExtension;
|
||||||
|
import org.eclipse.hawkbit.repository.test.util.TestLoggerExtension;
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||||
import org.eclipse.hawkbit.rest.RestConfiguration;
|
import org.eclipse.hawkbit.rest.RestConfiguration;
|
||||||
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
|
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
|
||||||
|
|||||||
@@ -1954,13 +1954,13 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
|||||||
|
|
||||||
private void awaitRunningState(final Long rolloutId) {
|
private void awaitRunningState(final Long rolloutId) {
|
||||||
awaitRollout().until(() -> SecurityContextSwitch
|
awaitRollout().until(() -> SecurityContextSwitch
|
||||||
.callAsPrivileged(() -> rolloutManagement.get(rolloutId))
|
.asPrivileged(() -> rolloutManagement.get(rolloutId))
|
||||||
.getStatus().equals(RolloutStatus.RUNNING));
|
.getStatus().equals(RolloutStatus.RUNNING));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void awaitActionStatus(final Long actionId, final Status status) {
|
private void awaitActionStatus(final Long actionId, final Status status) {
|
||||||
awaitRollout().until(() -> SecurityContextSwitch
|
awaitRollout().until(() -> SecurityContextSwitch
|
||||||
.callAsPrivileged(() -> deploymentManagement.findAction(actionId).orElseThrow(NoSuchElementException::new))
|
.asPrivileged(() -> deploymentManagement.findAction(actionId).orElseThrow(NoSuchElementException::new))
|
||||||
.getStatus().equals(status));
|
.getStatus().equals(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,22 +9,22 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.mgmt.rest.resource;
|
package org.eclipse.hawkbit.mgmt.rest.resource;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
import static org.eclipse.hawkbit.repository.TargetManagement.Create.builder;
|
||||||
import org.hamcrest.Matchers;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.eclipse.hawkbit.repository.TargetManagement.Create.*;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
|
||||||
|
|
||||||
public class MgmtTargetGroupResourceTest extends AbstractManagementApiIntegrationTest {
|
public class MgmtTargetGroupResourceTest extends AbstractManagementApiIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user