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:
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
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.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.SystemManagement;
|
||||
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.MultiActionAssignEvent;
|
||||
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.TargetAttributesRequestedServiceEvent;
|
||||
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.ActionProperties;
|
||||
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.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.util.IpUtil;
|
||||
import org.eclipse.hawkbit.utils.IpUtil;
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.core.MessageBuilder;
|
||||
import org.springframework.amqp.core.MessageProperties;
|
||||
@@ -94,43 +94,36 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
||||
|
||||
private final ArtifactUrlResolver artifactUrlHandler;
|
||||
private final AmqpMessageSenderService amqpSenderService;
|
||||
private final SystemSecurityContext systemSecurityContext;
|
||||
private final SystemManagement systemManagement;
|
||||
private final TargetManagement<? extends Target> targetManagement;
|
||||
private final SoftwareModuleManagement<? extends SoftwareModule> softwareModuleManagement;
|
||||
private final DistributionSetManagement<? extends DistributionSet> distributionSetManagement;
|
||||
private final DeploymentManagement deploymentManagement;
|
||||
private final TenantConfigurationManagement tenantConfigurationManagement;
|
||||
private final RepositoryProperties repositoryProperties;
|
||||
|
||||
@SuppressWarnings("java:S107")
|
||||
protected AmqpMessageDispatcherService(
|
||||
final RabbitTemplate rabbitTemplate,
|
||||
final AmqpMessageSenderService amqpSenderService, final ArtifactUrlResolver artifactUrlHandler,
|
||||
final SystemSecurityContext systemSecurityContext, final SystemManagement systemManagement,
|
||||
final SystemManagement systemManagement,
|
||||
final TargetManagement<? extends Target> targetManagement,
|
||||
final SoftwareModuleManagement<? extends SoftwareModule> softwareModuleManagement,
|
||||
final DistributionSetManagement<? extends DistributionSet> distributionSetManagement,
|
||||
final DeploymentManagement deploymentManagement,
|
||||
final TenantConfigurationManagement tenantConfigurationManagement,
|
||||
final RepositoryProperties repositoryProperties) {
|
||||
super(rabbitTemplate);
|
||||
this.artifactUrlHandler = artifactUrlHandler;
|
||||
this.amqpSenderService = amqpSenderService;
|
||||
this.systemSecurityContext = systemSecurityContext;
|
||||
this.systemManagement = systemManagement;
|
||||
this.targetManagement = targetManagement;
|
||||
this.softwareModuleManagement = softwareModuleManagement;
|
||||
this.distributionSetManagement = distributionSetManagement;
|
||||
this.deploymentManagement = deploymentManagement;
|
||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
||||
this.repositoryProperties = repositoryProperties;
|
||||
}
|
||||
|
||||
public boolean isBatchAssignmentsEnabled() {
|
||||
return systemSecurityContext.runAsSystem(() ->
|
||||
tenantConfigurationManagement
|
||||
.getConfigurationValue(BATCH_ASSIGNMENTS_ENABLED, Boolean.class).getValue());
|
||||
return TenantConfigHelper.getAsSystem(BATCH_ASSIGNMENTS_ENABLED, Boolean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,9 +177,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
||||
protected DmfDownloadAndUpdateRequest createDownloadAndUpdateRequest(
|
||||
final Target target, final Long actionId, final Map<SoftwareModule, Map<String, String>> softwareModules) {
|
||||
return new DmfDownloadAndUpdateRequest(
|
||||
actionId,
|
||||
systemSecurityContext.runAsSystem(target::getSecurityToken),
|
||||
convertToAmqpSoftwareModules(target, softwareModules));
|
||||
actionId, asSystem(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) {
|
||||
final Message message = MessageBuilder
|
||||
.withBody(String.valueOf(System.currentTimeMillis()).getBytes())
|
||||
.withBody(String.valueOf(java.lang.System.currentTimeMillis()).getBytes())
|
||||
.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)
|
||||
.setCorrelationId(ping.getMessageProperties().getCorrelationId())
|
||||
.setHeader(MessageHeaderKey.TYPE, MessageType.PING_RESPONSE)
|
||||
@@ -251,16 +242,9 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
||||
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(
|
||||
final Target target, final Long actionId, final Map<SoftwareModule, Map<String, String>> softwareModules) {
|
||||
return new DmfConfirmRequest(
|
||||
actionId,
|
||||
systemSecurityContext.runAsSystem(target::getSecurityToken),
|
||||
convertToAmqpSoftwareModules(target, softwareModules));
|
||||
return new DmfConfirmRequest(actionId, asSystem(target::getSecurityToken), convertToAmqpSoftwareModules(target, softwareModules));
|
||||
}
|
||||
|
||||
void sendMultiActionRequestToTarget(
|
||||
@@ -580,13 +564,14 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
||||
final Map<SoftwareModule, Map<String, String>> modules) {
|
||||
final List<DmfTarget> dmfTargets = targets.stream()
|
||||
.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();
|
||||
|
||||
// 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 DmfBatchDownloadAndUpdateRequest batchRequest = new DmfBatchDownloadAndUpdateRequest(
|
||||
System.currentTimeMillis(),
|
||||
java.lang.System.currentTimeMillis(),
|
||||
dmfTargets,
|
||||
Optional.ofNullable(modules)
|
||||
.map(Map::entrySet)
|
||||
@@ -594,7 +579,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
||||
.map(stream -> stream.map(entry -> convertToAmqpSoftwareModule(firstTarget, entry)).toList())
|
||||
.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
|
||||
final ActionProperties firstAction = actions.values().iterator().next();
|
||||
final Message message = getMessageConverter().toMessage(
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
package org.eclipse.hawkbit.amqp;
|
||||
|
||||
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.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -28,6 +26,7 @@ import jakarta.validation.constraints.NotNull;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.MessageHeaderKey;
|
||||
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.DmfCreateThing;
|
||||
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.ControllerManagement;
|
||||
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
import org.eclipse.hawkbit.repository.UpdateMode;
|
||||
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
||||
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.ActionStatusCreate;
|
||||
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.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
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.core.Message;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
@@ -82,30 +80,16 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
||||
|
||||
private final AmqpMessageDispatcherService amqpMessageDispatcherService;
|
||||
private final ConfirmationManagement confirmationManagement;
|
||||
private final TenantConfigurationManagement tenantConfigurationManagement;
|
||||
private final SystemSecurityContext systemSecurityContext;
|
||||
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(
|
||||
final RabbitTemplate rabbitTemplate,
|
||||
final AmqpMessageDispatcherService amqpMessageDispatcherService,
|
||||
final ControllerManagement controllerManagement, final SystemSecurityContext systemSecurityContext,
|
||||
final TenantConfigurationManagement tenantConfigurationManagement, final ConfirmationManagement confirmationManagement) {
|
||||
final ControllerManagement controllerManagement,
|
||||
final ConfirmationManagement confirmationManagement) {
|
||||
super(rabbitTemplate);
|
||||
this.amqpMessageDispatcherService = amqpMessageDispatcherService;
|
||||
this.controllerManagement = controllerManagement;
|
||||
this.systemSecurityContext = systemSecurityContext;
|
||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
||||
this.confirmationManagement = confirmationManagement;
|
||||
}
|
||||
|
||||
@@ -331,7 +315,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
||||
}
|
||||
|
||||
private void sendUpdateCommandToTarget(final Target target) {
|
||||
if (isMultiAssignmentsEnabled()) {
|
||||
if (TenantConfigHelper.getAsSystem(TenantConfigurationProperties.TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED, Boolean.class)) {
|
||||
sendCurrentActionsAsMultiActionToTarget(target);
|
||||
} else {
|
||||
sendOldestActionToTarget(target);
|
||||
@@ -456,8 +440,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
||||
} else if (actionUpdateStatus.getActionStatus() == DmfActionStatus.DENIED) {
|
||||
updatedAction = confirmationManagement.denyAction(action.getId(), actionUpdateStatus.getCode(), messages);
|
||||
} else {
|
||||
final ActionStatusCreateBuilder actionStatus = ActionStatusCreate.builder().actionId(action.getId())
|
||||
.status(status);
|
||||
final ActionStatusCreateBuilder actionStatus = ActionStatusCreate.builder().actionId(action.getId()).status(status);
|
||||
Optional.ofNullable(actionUpdateStatus.getCode()).ifPresentOrElse(
|
||||
code -> {
|
||||
actionStatus.code(code);
|
||||
@@ -491,12 +474,4 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
||||
|
||||
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 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.rabbit.connection.CorrelationData;
|
||||
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.SystemManagement;
|
||||
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.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.springframework.amqp.core.Binding;
|
||||
import org.springframework.amqp.core.BindingBuilder;
|
||||
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.
|
||||
*
|
||||
* @return the receiver queue
|
||||
@@ -227,12 +225,10 @@ public class DmfApiConfiguration {
|
||||
public AmqpMessageHandlerService amqpMessageHandlerService(
|
||||
final RabbitTemplate rabbitTemplate,
|
||||
final AmqpMessageDispatcherService amqpMessageDispatcherService,
|
||||
final ControllerManagement controllerManagement, final SystemSecurityContext systemSecurityContext,
|
||||
final TenantConfigurationManagement tenantConfigurationManagement,
|
||||
final ControllerManagement controllerManagement,
|
||||
final ConfirmationManagement confirmationManagement) {
|
||||
return new AmqpMessageHandlerService(
|
||||
rabbitTemplate, amqpMessageDispatcherService, controllerManagement,
|
||||
systemSecurityContext, tenantConfigurationManagement, confirmationManagement);
|
||||
rabbitTemplate, amqpMessageDispatcherService, controllerManagement, confirmationManagement);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,14 +262,14 @@ public class DmfApiConfiguration {
|
||||
AmqpMessageDispatcherService amqpMessageDispatcherService(
|
||||
final RabbitTemplate rabbitTemplate,
|
||||
final AmqpMessageSenderService amqpSenderService, final ArtifactUrlResolver artifactUrlHandler,
|
||||
final SystemSecurityContext systemSecurityContext, final SystemManagement systemManagement,
|
||||
final SystemManagement systemManagement,
|
||||
final TargetManagement<? extends Target> targetManagement,
|
||||
final DistributionSetManagement<? extends DistributionSet> distributionSetManagement,
|
||||
final SoftwareModuleManagement<? extends SoftwareModule> softwareModuleManagement, final DeploymentManagement deploymentManagement,
|
||||
final TenantConfigurationManagement tenantConfigurationManagement, final RepositoryProperties repositoryProperties) {
|
||||
final RepositoryProperties repositoryProperties) {
|
||||
return new AmqpMessageDispatcherService(rabbitTemplate, amqpSenderService, artifactUrlHandler,
|
||||
systemSecurityContext, systemManagement, targetManagement, softwareModuleManagement, distributionSetManagement,
|
||||
deploymentManagement, tenantConfigurationManagement, repositoryProperties);
|
||||
systemManagement, targetManagement, softwareModuleManagement, distributionSetManagement,
|
||||
deploymentManagement, repositoryProperties);
|
||||
}
|
||||
|
||||
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {
|
||||
|
||||
Reference in New Issue
Block a user