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:
Avgustin Marinov
2025-11-27 13:07:49 +02:00
committed by GitHub
parent 58dbc32a80
commit f6f62db0ad
274 changed files with 2534 additions and 4458 deletions

View File

@@ -11,6 +11,8 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
import static org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility.sanitizeActionSortParam;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.audit.AuditLog;
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.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RestController
@ConditionalOnProperty(name = "hawkbit.rest.MgmtActionResource.enabled", matchIfMissing = true)

View File

@@ -10,9 +10,9 @@
package org.eclipse.hawkbit.mgmt.rest.resource;
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.rest.api.MgmtBasicAuthRestApi;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
@@ -25,18 +25,12 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
public class MgmtBasicAuthResource implements MgmtBasicAuthRestApi {
private final TenantAware tenantAware;
public MgmtBasicAuthResource(final TenantAware tenantAware) {
this.tenantAware = tenantAware;
}
@Override
@AuditLog(entity = "BasicAuth", type = AuditLog.Type.READ, description = "Validate Basic Auth")
public ResponseEntity<MgmtUserInfo> validateBasicAuth() {
final MgmtUserInfo userInfo = new MgmtUserInfo();
userInfo.setTenant(tenantAware.getCurrentTenant());
userInfo.setUsername(tenantAware.getCurrentUsername());
userInfo.setTenant(AccessContext.tenant());
userInfo.setUsername(AccessContext.actor());
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {
userInfo.setPermissions(authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).toArray(String[]::new));

View File

@@ -55,8 +55,8 @@ import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
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.DistributionSet;
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.Target;
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.Pageable;
import org.springframework.http.HttpStatus;
@@ -89,7 +87,6 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
private final DeploymentManagement deployManagement;
private final SystemManagement systemManagement;
private final MgmtDistributionSetMapper mgmtDistributionSetMapper;
private final TenantConfigHelper tenantConfigHelper;
@SuppressWarnings("java:S107")
MgmtDistributionSetResource(
@@ -99,9 +96,9 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
final DistributionSetInvalidationManagement distributionSetInvalidationManagement,
final TargetManagement<? extends Target> targetManagement,
final TargetFilterQueryManagement<? extends TargetFilterQuery> targetFilterQueryManagement,
final DeploymentManagement deployManagement, final TenantConfigurationManagement tenantConfigurationManagement,
final DeploymentManagement deployManagement,
final MgmtDistributionSetMapper mgmtDistributionSetMapper,
final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext) {
final SystemManagement systemManagement) {
this.softwareModuleManagement = softwareModuleManagement;
this.distributionSetManagement = distributionSetManagement;
this.distributionSetTypeManagement = distributionSetTypeManagement;
@@ -109,7 +106,6 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
this.targetManagement = targetManagement;
this.targetFilterQueryManagement = targetFilterQueryManagement;
this.deployManagement = deployManagement;
this.tenantConfigHelper = TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement);
this.mgmtDistributionSetMapper = mgmtDistributionSetMapper;
this.systemManagement = systemManagement;
}
@@ -209,7 +205,7 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
}
return ResponseEntity.ok(new PagedList<>(
MgmtTargetMapper.toResponse(targetsAssignedDS.getContent(), tenantConfigHelper), targetsAssignedDS.getTotalElements()));
MgmtTargetMapper.toResponse(targetsAssignedDS.getContent()), targetsAssignedDS.getTotalElements()));
}
@Override
@@ -227,7 +223,7 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
}
return ResponseEntity.ok(new PagedList<>(
MgmtTargetMapper.toResponse(targetsInstalledDS.getContent(), tenantConfigHelper), targetsInstalledDS.getTotalElements()));
MgmtTargetMapper.toResponse(targetsInstalledDS.getContent()), targetsInstalledDS.getTotalElements()));
}
@Override
@@ -239,7 +235,8 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
.findByAutoAssignDSAndRsql(distributionSetId, rsqlParam, pageable);
return ResponseEntity.ok(new PagedList<>(
MgmtTargetFilterQueryMapper.toResponse(targetFilterQueries.getContent(), tenantConfigHelper.isConfirmationFlowEnabled(), false),
MgmtTargetFilterQueryMapper.toResponse(
targetFilterQueries.getContent(), TenantConfigHelper.isUserConfirmationFlowEnabled(), false),
targetFilterQueries.getTotalElements()));
}
@@ -256,13 +253,13 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
final List<DeploymentRequest> deploymentRequests = assignments.stream().map(dsAssignment -> {
final boolean isConfirmationRequired = dsAssignment.getConfirmationRequired() == null
? tenantConfigHelper.isConfirmationFlowEnabled()
? TenantConfigHelper.isUserConfirmationFlowEnabled()
: dsAssignment.getConfirmationRequired();
return MgmtDeploymentRequestMapper.createAssignmentRequestBuilder(dsAssignment, distributionSetId)
.confirmationRequired(isConfirmationRequired).build();
}).toList();
final List<DistributionSetAssignmentResult> assignmentResults = deployManagement.assignDistributionSets(deploymentRequests);
final List<DistributionSetAssignmentResult> assignmentResults = deployManagement.assignDistributionSets(deploymentRequests, null);
return ResponseEntity.ok(mgmtDistributionSetMapper.toResponse(assignmentResults));
}

View File

@@ -80,7 +80,7 @@ public class MgmtOpenApiConfiguration {
private static ServerVariable tenantSeverVariable() {
final ServerVariable tenantServerVariable = new ServerVariable();
tenantServerVariable.setDescription("Tenant identifier");
tenantServerVariable.setDescription("AccessContext identifier");
tenantServerVariable.setDefault("DEFAULT");
return tenantServerVariable;
}

View File

@@ -37,9 +37,9 @@ import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.RolloutManagement.Create;
import org.eclipse.hawkbit.repository.RolloutManagement.GroupCreate;
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.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Rollout;
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.Target;
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.Pageable;
import org.springframework.http.HttpStatus;
@@ -66,19 +64,15 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
private final RolloutGroupManagement rolloutGroupManagement;
private final DistributionSetManagement<? extends DistributionSet> distributionSetManagement;
private final TargetFilterQueryManagement<? extends TargetFilterQuery> targetFilterQueryManagement;
private final TenantConfigHelper tenantConfigHelper;
MgmtRolloutResource(
final RolloutManagement rolloutManagement, final RolloutGroupManagement rolloutGroupManagement,
final DistributionSetManagement<? extends DistributionSet> distributionSetManagement,
final TargetFilterQueryManagement<? extends TargetFilterQuery> targetFilterQueryManagement,
final SystemSecurityContext systemSecurityContext,
final TenantConfigurationManagement tenantConfigurationManagement) {
final TargetFilterQueryManagement<? extends TargetFilterQuery> targetFilterQueryManagement) {
this.rolloutManagement = rolloutManagement;
this.rolloutGroupManagement = rolloutGroupManagement;
this.distributionSetManagement = distributionSetManagement;
this.targetFilterQueryManagement = targetFilterQueryManagement;
this.tenantConfigHelper = TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement);
}
@Override
@@ -121,7 +115,7 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
final DistributionSet distributionSet = distributionSetManagement.getValidAndComplete(rolloutRequestBody.getDistributionSetId());
final RolloutGroupConditions rolloutGroupConditions = MgmtRolloutMapper.fromRequest(rolloutRequestBody, true);
final Create create = MgmtRolloutMapper.fromRequest(rolloutRequestBody, distributionSet);
final boolean confirmationFlowActive = tenantConfigHelper.isConfirmationFlowEnabled();
final boolean confirmationFlowActive = TenantConfigHelper.isUserConfirmationFlowEnabled();
final Rollout rollout;
if (rolloutRequestBody.getGroups() != null) {
@@ -226,7 +220,7 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
}
final List<MgmtRolloutGroupResponseBody> rest = MgmtRolloutMapper.toResponseRolloutGroup(
rolloutGroups.getContent(), tenantConfigHelper.isConfirmationFlowEnabled(), isFullMode);
rolloutGroups.getContent(), TenantConfigHelper.isUserConfirmationFlowEnabled(), isFullMode);
return ResponseEntity.ok(new PagedList<>(rest, rolloutGroups.getTotalElements()));
}
@@ -240,7 +234,7 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
}
return ResponseEntity.ok(MgmtRolloutMapper.toResponseRolloutGroup(
rolloutGroup, true, tenantConfigHelper.isConfirmationFlowEnabled()));
rolloutGroup, true, TenantConfigHelper.isUserConfirmationFlowEnabled()));
}
@Override
@@ -255,7 +249,7 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
} else {
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()));
}

View File

@@ -22,6 +22,8 @@ import java.util.Optional;
import jakarta.validation.ValidationException;
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.mgmt.json.model.PagedList;
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.SoftwareModuleTypeManagement;
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.model.Artifact;
import org.eclipse.hawkbit.repository.model.ArtifactUpload;

View File

@@ -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.repository.TargetFilterQueryManagement;
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.helper.TenantConfigHelper;
import org.eclipse.hawkbit.repository.model.DistributionSet;
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.Pageable;
import org.springframework.http.HttpStatus;
@@ -47,14 +45,9 @@ import org.springframework.web.bind.annotation.RestController;
public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestApi {
private final TargetFilterQueryManagement<? extends TargetFilterQuery> filterManagement;
private final TenantConfigHelper tenantConfigHelper;
MgmtTargetFilterQueryResource(
final TargetFilterQueryManagement<? extends TargetFilterQuery> filterManagement,
final SystemSecurityContext systemSecurityContext,
final TenantConfigurationManagement tenantConfigurationManagement) {
MgmtTargetFilterQueryResource(final TargetFilterQueryManagement<? extends TargetFilterQuery> filterManagement) {
this.filterManagement = filterManagement;
this.tenantConfigHelper = TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement);
}
@Override
@@ -62,7 +55,7 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
final TargetFilterQuery findTarget = findFilterWithExceptionIfNotFound(filterId);
// to single response include poll status
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(findTarget,
tenantConfigHelper.isConfirmationFlowEnabled(), true);
TenantConfigHelper.isUserConfirmationFlowEnabled(), true);
MgmtTargetFilterQueryMapper.addLinks(response);
return ResponseEntity.ok(response);
@@ -82,8 +75,8 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
final boolean isRepresentationFull = parseRepresentationMode(representationModeParam) == MgmtRepresentationMode.FULL;
final List<MgmtTargetFilterQuery> rest = MgmtTargetFilterQueryMapper
.toResponse(findTargetFiltersAll.getContent(), tenantConfigHelper.isConfirmationFlowEnabled(), isRepresentationFull);
final List<MgmtTargetFilterQuery> rest = MgmtTargetFilterQueryMapper.toResponse(
findTargetFiltersAll.getContent(), TenantConfigHelper.isUserConfirmationFlowEnabled(), isRepresentationFull);
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 MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(
createdTarget, tenantConfigHelper.isConfirmationFlowEnabled(), false);
createdTarget, TenantConfigHelper.isUserConfirmationFlowEnabled(), false);
MgmtTargetFilterQueryMapper.addLinks(response);
return new ResponseEntity<>(response, HttpStatus.CREATED);
@@ -108,7 +101,7 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
.build());
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(updateFilter,
tenantConfigHelper.isConfirmationFlowEnabled(), false);
TenantConfigHelper.isUserConfirmationFlowEnabled(), false);
MgmtTargetFilterQueryMapper.addLinks(response);
return ResponseEntity.ok(response);
@@ -141,7 +134,7 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
public ResponseEntity<MgmtTargetFilterQuery> postAssignedDistributionSet(
final Long filterId, final MgmtDistributionSetAutoAssignment autoAssignRequest) {
final boolean confirmationRequired = autoAssignRequest.getConfirmationRequired() == null
? tenantConfigHelper.isConfirmationFlowEnabled()
? TenantConfigHelper.isUserConfirmationFlowEnabled()
: autoAssignRequest.getConfirmationRequired();
final AutoAssignDistributionSetUpdate update = MgmtTargetFilterQueryMapper
@@ -150,7 +143,7 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
final TargetFilterQuery updateFilter = filterManagement.updateAutoAssignDS(update);
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(updateFilter,
tenantConfigHelper.isConfirmationFlowEnabled(), false);
TenantConfigHelper.isUserConfirmationFlowEnabled(), false);
MgmtTargetFilterQueryMapper.addLinks(response);
return ResponseEntity.ok(response);

View File

@@ -9,6 +9,10 @@
*/
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 org.eclipse.hawkbit.mgmt.json.model.PagedList;
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.util.PagingUtility;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
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.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility.sanitizeTargetSortParam;
@Slf4j
@RestController
public class MgmtTargetGroupResource implements MgmtTargetGroupRestApi {
private final TargetManagement<? extends Target> targetManagement;
private final TenantConfigHelper tenantConfigHelper;
public MgmtTargetGroupResource(
final TargetManagement <? extends Target>targetManagement,
final TenantConfigurationManagement tenantConfigurationManagement, final SystemSecurityContext systemSecurityContext) {
final TargetManagement <? extends Target>targetManagement) {
this.targetManagement = targetManagement;
this.tenantConfigHelper = TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement);
}
@Override
@@ -50,7 +44,7 @@ public class MgmtTargetGroupResource implements MgmtTargetGroupRestApi {
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()));
}
@@ -61,7 +55,7 @@ public class MgmtTargetGroupResource implements MgmtTargetGroupRestApi {
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()));
}

View File

@@ -56,9 +56,9 @@ import org.eclipse.hawkbit.repository.ConfirmationManagement;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
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.InvalidConfirmationFeedbackException;
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.ActionStatus;
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.TargetTag;
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.Pageable;
import org.springframework.data.domain.Slice;
@@ -91,27 +89,24 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
private final DeploymentManagement deploymentManagement;
private final MgmtTargetMapper mgmtTargetMapper;
private final MgmtDistributionSetMapper mgmtDistributionSetMapper;
private final TenantConfigHelper tenantConfigHelper;
MgmtTargetResource(
final TargetManagement<? extends Target> targetManagement, final TargetTypeManagement<? extends TargetType> targetTypeManagement,
final DeploymentManagement deploymentManagement, final ConfirmationManagement confirmationManagement,
final MgmtTargetMapper mgmtTargetMapper, final MgmtDistributionSetMapper mgmtDistributionSetMapper,
final SystemSecurityContext systemSecurityContext, final TenantConfigurationManagement tenantConfigurationManagement) {
final MgmtTargetMapper mgmtTargetMapper, final MgmtDistributionSetMapper mgmtDistributionSetMapper) {
this.targetManagement = targetManagement;
this.targetTypeManagement = targetTypeManagement;
this.deploymentManagement = deploymentManagement;
this.confirmationManagement = confirmationManagement;
this.mgmtTargetMapper = mgmtTargetMapper;
this.mgmtDistributionSetMapper = mgmtDistributionSetMapper;
this.tenantConfigHelper = TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement);
}
@Override
public ResponseEntity<MgmtTarget> getTarget(final String targetId) {
final Target findTarget = targetManagement.getByControllerId(targetId);
// to single response include poll status
final MgmtTarget response = MgmtTargetMapper.toResponse(findTarget, tenantConfigHelper, null);
final MgmtTarget response = MgmtTargetMapper.toResponse(findTarget, null);
MgmtTargetMapper.addTargetLinks(response);
return ResponseEntity.ok(response);
@@ -128,7 +123,7 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
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()));
}
@@ -137,7 +132,7 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
log.debug("creating {} targets", targets.size());
final Collection<? extends Target> createdTargets = this.targetManagement.create(mgmtTargetMapper.fromRequest(targets));
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
@@ -166,7 +161,7 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
.requestControllerAttributes(targetRest.getRequestAttributes())
.build());
final MgmtTarget response = MgmtTargetMapper.toResponse(updateTarget, tenantConfigHelper, null);
final MgmtTarget response = MgmtTargetMapper.toResponse(updateTarget, null);
MgmtTargetMapper.addTargetLinks(response);
return ResponseEntity.ok(response);
@@ -399,14 +394,13 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
final List<DeploymentRequest> deploymentRequests = dsAssignments.stream().map(dsAssignment -> {
final boolean isConfirmationRequired = dsAssignment.getConfirmationRequired() == null
? tenantConfigHelper.isConfirmationFlowEnabled()
? TenantConfigHelper.isUserConfirmationFlowEnabled()
: dsAssignment.getConfirmationRequired();
return MgmtDeploymentRequestMapper.createAssignmentRequestBuilder(dsAssignment, targetId)
.confirmationRequired(isConfirmationRequired).build();
}).toList();
final List<DistributionSetAssignmentResult> assignmentResults = deploymentManagement
.assignDistributionSets(deploymentRequests);
final List<DistributionSetAssignmentResult> assignmentResults = deploymentManagement.assignDistributionSets(deploymentRequests, null);
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) {
return object == null ? null : extractMethod.apply(object);
return ObjectUtils.isEmpty(object) ? null : extractMethod.apply(object);
}
}

View File

@@ -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.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.Target;
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.Pageable;
import org.springframework.http.HttpStatus;
@@ -48,14 +45,11 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
private final TargetTagManagement<? extends TargetTag> tagManagement;
private final TargetManagement<? extends Target> targetManagement;
private final TenantConfigHelper tenantConfigHelper;
MgmtTargetTagResource(
final TargetTagManagement<? extends TargetTag> tagManagement, final TargetManagement<? extends Target> targetManagement,
final SystemSecurityContext securityContext, final TenantConfigurationManagement configurationManagement) {
final TargetTagManagement<? extends TargetTag> tagManagement, final TargetManagement<? extends Target> targetManagement) {
this.tagManagement = tagManagement;
this.targetManagement = targetManagement;
tenantConfigHelper = TenantConfigHelper.usingContext(securityContext, configurationManagement);
}
@Override
@@ -129,7 +123,7 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
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()));
}

View File

@@ -33,7 +33,6 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RestController;
/**

View File

@@ -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.resource.mapper.MgmtTenantManagementMapper;
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.TenantConfigurationValidatorException;
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
import org.springframework.http.HttpStatus;
@@ -38,22 +38,19 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi {
private final TenantConfigurationManagement tenantConfigurationManagement;
private final TenantConfigurationProperties tenantConfigurationProperties;
private final SystemManagement systemManagement;
MgmtTenantManagementResource(
final TenantConfigurationManagement tenantConfigurationManagement,
final TenantConfigurationProperties tenantConfigurationProperties,
final SystemManagement systemManagement) {
this.tenantConfigurationManagement = tenantConfigurationManagement;
this.tenantConfigurationProperties = tenantConfigurationProperties;
this.systemManagement = systemManagement;
}
@Override
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<>();
tenantConfigurationProperties.getConfigurationKeys().forEach(key -> {
try {
@@ -74,14 +71,14 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
}
@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) {
//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)) {
return ResponseEntity.badRequest().build();
}
tenantConfigurationManagement.deleteConfiguration(keyName);
TenantConfigHelper.getTenantConfigurationManagement().deleteConfiguration(keyName);
log.debug("{} config value deleted, return status {}", keyName, HttpStatus.OK);
return ResponseEntity.noContent().build();
@@ -93,7 +90,7 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
}
@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(
final String keyName, final MgmtSystemTenantConfigurationValueRequest configurationValueRest) {
Serializable configurationValue = configurationValueRest.getValue();
@@ -101,7 +98,8 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
if (isDefaultDistributionSetTypeKey(keyName)) {
responseUpdatedValue = updateDefaultDsType(configurationValue);
} else {
final TenantConfigurationValue<? extends Serializable> updatedTenantConfigurationValue = tenantConfigurationManagement
final TenantConfigurationValue<? extends Serializable> updatedTenantConfigurationValue = TenantConfigHelper
.getTenantConfigurationManagement()
.addOrUpdateConfiguration(keyName, configurationValueRest.getValue());
responseUpdatedValue = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(keyName, updatedTenantConfigurationValue);
}
@@ -110,7 +108,7 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
}
@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(
final Map<String, Serializable> configurationValueMap) {
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
final Map<String, TenantConfigurationValue<Serializable>> tenantConfigurationValues;
try {
tenantConfigurationValues = tenantConfigurationManagement.addOrUpdateConfiguration(configurationValueMap);
tenantConfigurationValues = TenantConfigHelper.getTenantConfigurationManagement().addOrUpdateConfiguration(configurationValueMap);
} catch (Exception ex) {
//if DefaultDsType was updated, rollback it in case of TenantConfiguration update.
if (updatedDefaultDsType != null) {
@@ -155,13 +153,13 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
}
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;
if (isDefaultDistributionSetTypeKey(keyName)) {
response = MgmtTenantManagementMapper.toResponseDefaultDsType(systemManagement.getTenantMetadata().getDefaultDsType().getId());
} else {
response = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(
keyName, tenantConfigurationManagement.getConfigurationValue(keyName));
keyName, TenantConfigHelper.getTenantConfigurationManagement().getConfigurationValue(keyName));
}
return response;
}

View File

@@ -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.resource.MgmtDownloadArtifactResource;
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.SoftwareModuleTypeManagement;
import org.eclipse.hawkbit.repository.SystemManagement;

View File

@@ -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.MgmtTargetTypeRestApi;
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.TargetManagement.Create;
import org.eclipse.hawkbit.repository.TargetTypeManagement;
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.ActionType;
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.Target;
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.util.IpUtil;
import org.eclipse.hawkbit.utils.TenantConfigHelper;
import org.eclipse.hawkbit.utils.IpUtil;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
@@ -119,30 +119,16 @@ public final class MgmtTargetMapper {
return response;
}
/**
* 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) {
public static List<MgmtTarget> toResponse(final Collection<? extends Target> targets) {
if (targets == null) {
return Collections.emptyList();
}
final Function<Target, PollStatus> pollStatusResolver = configHelper.pollStatusResolver();
return new ResponseList<>(
targets.stream().map(target -> toResponse(target, configHelper, pollStatusResolver)).toList());
final Function<Target, PollStatus> pollStatusResolver = TenantConfigHelper.pollStatusResolver();
return new ResponseList<>(targets.stream().map(target -> toResponse(target, pollStatusResolver)).toList());
}
/**
* 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) {
public static MgmtTarget toResponse(final Target target, final Function<Target, PollStatus> pollStatusResolver) {
if (target == null) {
return null;
}
@@ -189,13 +175,14 @@ public final class MgmtTargetMapper {
targetRest.setTargetType(target.getTargetType().getId());
targetRest.setTargetTypeName(target.getTargetType().getName());
}
if (configHelper.isConfirmationFlowEnabled()) {
if (TenantConfigHelper.isUserConfirmationFlowEnabled()) {
targetRest.setAutoConfirmActive(target.getAutoConfirmationStatus() != null);
}
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;
}

View File

@@ -12,11 +12,11 @@ package org.eclipse.hawkbit.mgmt.rest.resource.util;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
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.ActionStatusFields;
import org.eclipse.hawkbit.repository.qfields.DistributionSetFields;
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.RolloutGroupFields;
import org.eclipse.hawkbit.repository.qfields.SoftwareModuleFields;