Remove DMF API dependency from security integration (#604)

* Dmf security token out of API.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Allow to override dispatching routines.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* TargetAssign event is bulk ready.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Completed Javadoc.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* readibility and fix serialization bug.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Fix sonar issue.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Simplify artifact management usage.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2017-12-07 15:55:09 +01:00
committed by GitHub
parent e22f25cc61
commit 5a6fc37a15
34 changed files with 289 additions and 348 deletions

View File

@@ -13,20 +13,18 @@ import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import org.eclipse.hawkbit.api.HostnameResolver; import org.eclipse.hawkbit.api.HostnameResolver;
import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
import org.eclipse.hawkbit.cache.DownloadArtifactCache; import org.eclipse.hawkbit.cache.DownloadArtifactCache;
import org.eclipse.hawkbit.cache.DownloadIdCache; import org.eclipse.hawkbit.cache.DownloadIdCache;
import org.eclipse.hawkbit.cache.DownloadType; import org.eclipse.hawkbit.cache.DownloadType;
import org.eclipse.hawkbit.dmf.json.model.DmfArtifact; import org.eclipse.hawkbit.dmf.json.model.DmfArtifact;
import org.eclipse.hawkbit.dmf.json.model.DmfArtifactHash; import org.eclipse.hawkbit.dmf.json.model.DmfArtifactHash;
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse; import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.ControllerManagement;
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.security.DmfTenantSecurityToken;
import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -188,54 +186,53 @@ public class AmqpAuthenticationMessageHandler extends BaseAmqpService {
return Optional.empty(); return Optional.empty();
} }
private static DmfArtifact convertDbArtifact(final AbstractDbArtifact dbArtifact) { private static DmfArtifact convertDbArtifact(final Artifact dbArtifact) {
final DmfArtifact artifact = new DmfArtifact(); final DmfArtifact artifact = new DmfArtifact();
artifact.setSize(dbArtifact.getSize()); artifact.setSize(dbArtifact.getSize());
final DbArtifactHash dbArtifactHash = dbArtifact.getHashes(); artifact.setHashes(new DmfArtifactHash(dbArtifact.getSha1Hash(), dbArtifact.getMd5Hash()));
artifact.setHashes(new DmfArtifactHash(dbArtifactHash.getSha1(), dbArtifactHash.getMd5()));
return artifact; return artifact;
} }
private Message handleAuthenticationMessage(final Message message) { private Message handleAuthenticationMessage(final Message message) {
final DmfDownloadResponse authentificationResponse = new DmfDownloadResponse(); final DmfDownloadResponse authenticationResponse = new DmfDownloadResponse();
final DmfTenantSecurityToken secruityToken = convertMessage(message, DmfTenantSecurityToken.class); final DmfTenantSecurityToken secruityToken = convertMessage(message, DmfTenantSecurityToken.class);
final FileResource fileResource = secruityToken.getFileResource(); final FileResource fileResource = secruityToken.getFileResource();
try { try {
SecurityContextHolder.getContext().setAuthentication(authenticationManager.doAuthenticate(secruityToken)); SecurityContextHolder.getContext().setAuthentication(authenticationManager.doAuthenticate(secruityToken));
final String sha1Hash = findArtifactByFileResource(fileResource).map(Artifact::getSha1Hash) final Artifact artifact = findArtifactByFileResource(fileResource)
.orElseThrow(EntityNotFoundException::new); .orElseThrow(EntityNotFoundException::new);
checkIfArtifactIsAssignedToTarget(secruityToken, sha1Hash); checkIfArtifactIsAssignedToTarget(secruityToken, artifact.getSha1Hash());
final DmfArtifact artifact = convertDbArtifact(artifactManagement.loadArtifactBinary(sha1Hash) final DmfArtifact dmfArtifact = convertDbArtifact(artifact);
.orElseThrow(() -> new EntityNotFoundException(Artifact.class, sha1Hash)));
authentificationResponse.setArtifact(artifact); authenticationResponse.setArtifact(dmfArtifact);
final String downloadId = UUID.randomUUID().toString(); final String downloadId = UUID.randomUUID().toString();
// SHA1 key is set, download by SHA1 // SHA1 key is set, download by SHA1
final DownloadArtifactCache downloadCache = new DownloadArtifactCache(DownloadType.BY_SHA1, sha1Hash); final DownloadArtifactCache downloadCache = new DownloadArtifactCache(DownloadType.BY_SHA1,
artifact.getSha1Hash());
cache.put(downloadId, downloadCache); cache.put(downloadId, downloadCache);
authentificationResponse.setDownloadUrl(UriComponentsBuilder authenticationResponse.setDownloadUrl(UriComponentsBuilder
.fromUri(hostnameResolver.resolveHostname().toURI()).path("/api/v1/downloadserver/downloadId/") .fromUri(hostnameResolver.resolveHostname().toURI()).path("/api/v1/downloadserver/downloadId/")
.path(tenantAware.getCurrentTenant()).path("/").path(downloadId).build().toUriString()); .path(tenantAware.getCurrentTenant()).path("/").path(downloadId).build().toUriString());
authentificationResponse.setResponseCode(HttpStatus.OK.value()); authenticationResponse.setResponseCode(HttpStatus.OK.value());
} catch (final BadCredentialsException | AuthenticationServiceException | CredentialsExpiredException e) { } catch (final BadCredentialsException | AuthenticationServiceException | CredentialsExpiredException e) {
LOG.error("Login failed", e); LOG.error("Login failed", e);
authentificationResponse.setResponseCode(HttpStatus.FORBIDDEN.value()); authenticationResponse.setResponseCode(HttpStatus.FORBIDDEN.value());
authentificationResponse.setMessage("Login failed"); authenticationResponse.setMessage("Login failed");
} catch (final URISyntaxException e) { } catch (final URISyntaxException e) {
LOG.error("URI build exception", e); LOG.error("URI build exception", e);
authentificationResponse.setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); authenticationResponse.setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
authentificationResponse.setMessage("Building download URI failed"); authenticationResponse.setMessage("Building download URI failed");
} catch (final EntityNotFoundException e) { } catch (final EntityNotFoundException e) {
final String errorMessage = "Artifact for resource " + fileResource + "not found "; final String errorMessage = "Artifact for resource " + fileResource + "not found ";
LOG.warn(errorMessage, e); LOG.warn(errorMessage, e);
authentificationResponse.setResponseCode(HttpStatus.NOT_FOUND.value()); authenticationResponse.setResponseCode(HttpStatus.NOT_FOUND.value());
authentificationResponse.setMessage(errorMessage); authenticationResponse.setMessage(errorMessage);
} }
return getMessageConverter().toMessage(authentificationResponse, message.getMessageProperties()); return getMessageConverter().toMessage(authenticationResponse, message.getMessageProperties());
} }
} }

View File

@@ -17,6 +17,7 @@ import org.eclipse.hawkbit.cache.DownloadIdCache;
import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings; import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings;
import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetManagement;
@@ -305,31 +306,14 @@ public class AmqpConfiguration {
tenantAware, ddiSecruityProperties, systemSecurityContext); tenantAware, ddiSecruityProperties, systemSecurityContext);
} }
/**
* Create the dispatcher bean.
*
* @param rabbitTemplate
* the rabbitTemplate
* @param amqpSenderService
* to send AMQP message
* @param artifactUrlHandler
* for generating download URLs
* @param systemSecurityContext
* for execution with system permissions
* @param systemManagement
* the systemManagement
* @param targetManagement
* to access target information
* @return the bean
*/
@Bean @Bean
@ConditionalOnMissingBean(AmqpMessageDispatcherService.class) @ConditionalOnMissingBean(AmqpMessageDispatcherService.class)
public AmqpMessageDispatcherService amqpMessageDispatcherService(final RabbitTemplate rabbitTemplate, AmqpMessageDispatcherService amqpMessageDispatcherService(final RabbitTemplate rabbitTemplate,
final AmqpMessageSenderService amqpSenderService, final ArtifactUrlHandler artifactUrlHandler, final AmqpMessageSenderService amqpSenderService, final ArtifactUrlHandler artifactUrlHandler,
final SystemSecurityContext systemSecurityContext, final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext, final SystemManagement systemManagement,
final TargetManagement targetManagement) { final TargetManagement targetManagement, final DistributionSetManagement distributionSetManagement) {
return new AmqpMessageDispatcherService(rabbitTemplate, amqpSenderService, artifactUrlHandler, return new AmqpMessageDispatcherService(rabbitTemplate, amqpSenderService, artifactUrlHandler,
systemSecurityContext, systemManagement, targetManagement, serviceMatcher); systemSecurityContext, systemManagement, targetManagement, serviceMatcher, distributionSetManagement);
} }
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() { private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {

View File

@@ -12,7 +12,6 @@ import java.util.List;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.SystemManagement;
@@ -23,6 +22,7 @@ import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousFilter;
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter;
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter;
import org.eclipse.hawkbit.security.DdiSecurityProperties; import org.eclipse.hawkbit.security.DdiSecurityProperties;
import org.eclipse.hawkbit.security.DmfTenantSecurityToken;
import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider; import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
import org.eclipse.hawkbit.security.PreAuthentificationFilter; import org.eclipse.hawkbit.security.PreAuthentificationFilter;
import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.security.SystemSecurityContext;

View File

@@ -26,6 +26,7 @@ import org.eclipse.hawkbit.dmf.json.model.DmfArtifact;
import org.eclipse.hawkbit.dmf.json.model.DmfArtifactHash; import org.eclipse.hawkbit.dmf.json.model.DmfArtifactHash;
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadAndUpdateRequest; import org.eclipse.hawkbit.dmf.json.model.DmfDownloadAndUpdateRequest;
import org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule; import org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
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.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
@@ -64,6 +65,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
private final SystemManagement systemManagement; private final SystemManagement systemManagement;
private final TargetManagement targetManagement; private final TargetManagement targetManagement;
private final ServiceMatcher serviceMatcher; private final ServiceMatcher serviceMatcher;
private final DistributionSetManagement distributionSetManagement;
/** /**
* Constructor. * Constructor.
@@ -83,11 +85,14 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
* @param serviceMatcher * @param serviceMatcher
* to check in cluster case if the message is from the same * to check in cluster case if the message is from the same
* cluster node * cluster node
* @param distributionSetManagement
* to retrieve modules
*/ */
public AmqpMessageDispatcherService(final RabbitTemplate rabbitTemplate, protected AmqpMessageDispatcherService(final RabbitTemplate rabbitTemplate,
final AmqpMessageSenderService amqpSenderService, final ArtifactUrlHandler artifactUrlHandler, final AmqpMessageSenderService amqpSenderService, final ArtifactUrlHandler artifactUrlHandler,
final SystemSecurityContext systemSecurityContext, final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext, final SystemManagement systemManagement,
final TargetManagement targetManagement, final ServiceMatcher serviceMatcher) { final TargetManagement targetManagement, final ServiceMatcher serviceMatcher,
final DistributionSetManagement distributionSetManagement) {
super(rabbitTemplate); super(rabbitTemplate);
this.artifactUrlHandler = artifactUrlHandler; this.artifactUrlHandler = artifactUrlHandler;
this.amqpSenderService = amqpSenderService; this.amqpSenderService = amqpSenderService;
@@ -95,6 +100,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
this.systemManagement = systemManagement; this.systemManagement = systemManagement;
this.targetManagement = targetManagement; this.targetManagement = targetManagement;
this.serviceMatcher = serviceMatcher; this.serviceMatcher = serviceMatcher;
this.distributionSetManagement = distributionSetManagement;
} }
/** /**
@@ -105,21 +111,54 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
* the object to be send. * the object to be send.
*/ */
@EventListener(classes = TargetAssignDistributionSetEvent.class) @EventListener(classes = TargetAssignDistributionSetEvent.class)
public void targetAssignDistributionSet(final TargetAssignDistributionSetEvent assignedEvent) { protected void targetAssignDistributionSet(final TargetAssignDistributionSetEvent assignedEvent) {
if (isNotFromSelf(assignedEvent)) { if (isNotFromSelf(assignedEvent)) {
return; return;
} }
LOG.debug("targetAssignDistributionSet retrieved for controller {}. I will forward it to DMF broker.", LOG.debug("targetAssignDistributionSet retrieved. I will forward it to DMF broker.");
assignedEvent.getControllerId());
targetManagement.getByControllerID(assignedEvent.getControllerId()) distributionSetManagement.get(assignedEvent.getDistributionSetId()).ifPresent(set ->
.ifPresent(target -> sendUpdateMessageToTarget(assignedEvent.getTenant(), target,
assignedEvent.getActionId(), assignedEvent.getModules()));
targetManagement.getByControllerID(assignedEvent.getActions().keySet())
.forEach(target -> sendUpdateMessageToTarget(assignedEvent.getTenant(), target,
assignedEvent.getActions().get(target.getControllerId()), set.getModules())));
} }
void sendUpdateMessageToTarget(final String tenant, final Target target, final Long actionId, /**
* Method to send a message to a RabbitMQ Exchange after the assignment of
* the Distribution set to a Target has been canceled.
*
* @param cancelEvent
* the object to be send.
*/
@EventListener(classes = CancelTargetAssignmentEvent.class)
protected void targetCancelAssignmentToDistributionSet(final CancelTargetAssignmentEvent cancelEvent) {
if (isNotFromSelf(cancelEvent)) {
return;
}
sendCancelMessageToTarget(cancelEvent.getTenant(), cancelEvent.getEntity().getControllerId(),
cancelEvent.getActionId(), cancelEvent.getEntity().getAddress());
}
/**
* Method to send a message to a RabbitMQ Exchange after a Target was
* deleted.
*
* @param deleteEvent
* the TargetDeletedEvent which holds the necessary data for
* sending a target delete message.
*/
@EventListener(classes = TargetDeletedEvent.class)
protected void targetDelete(final TargetDeletedEvent deleteEvent) {
if (isNotFromSelf(deleteEvent)) {
return;
}
sendDeleteMessage(deleteEvent.getTenant(), deleteEvent.getControllerId(), deleteEvent.getTargetAddress());
}
protected void sendUpdateMessageToTarget(final String tenant, final Target target, final Long actionId,
final Collection<SoftwareModule> modules) { final Collection<SoftwareModule> modules) {
final URI targetAdress = target.getAddress(); final URI targetAdress = target.getAddress();
@@ -144,7 +183,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
amqpSenderService.sendMessage(message, targetAdress); amqpSenderService.sendMessage(message, targetAdress);
} }
void sendPingReponseToDmfReceiver(final Message ping, final String tenant, final String virtualHost) { protected void sendPingReponseToDmfReceiver(final Message ping, final String tenant, final String virtualHost) {
final Message message = MessageBuilder.withBody(String.valueOf(System.currentTimeMillis()).getBytes()) final Message message = MessageBuilder.withBody(String.valueOf(System.currentTimeMillis()).getBytes())
.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN) .setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)
.setCorrelationId(ping.getMessageProperties().getCorrelationId()) .setCorrelationId(ping.getMessageProperties().getCorrelationId())
@@ -155,40 +194,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
IpUtil.createAmqpUri(virtualHost, ping.getMessageProperties().getReplyTo())); IpUtil.createAmqpUri(virtualHost, ping.getMessageProperties().getReplyTo()));
} }
/** protected void sendDeleteMessage(final String tenant, final String controllerId, final String targetAddress) {
* Method to send a message to a RabbitMQ Exchange after the assignment of
* the Distribution set to a Target has been canceled.
*
* @param cancelEvent
* the object to be send.
*/
@EventListener(classes = CancelTargetAssignmentEvent.class)
public void targetCancelAssignmentToDistributionSet(final CancelTargetAssignmentEvent cancelEvent) {
if (isNotFromSelf(cancelEvent)) {
return;
}
sendCancelMessageToTarget(cancelEvent.getTenant(), cancelEvent.getEntity().getControllerId(),
cancelEvent.getActionId(), cancelEvent.getEntity().getAddress());
}
/**
* Method to send a message to a RabbitMQ Exchange after a Target was
* deleted.
*
* @param deleteEvent
* the TargetDeletedEvent which holds the necessary data for
* sending a target delete message.
*/
@EventListener(classes = TargetDeletedEvent.class)
public void targetDelete(final TargetDeletedEvent deleteEvent) {
if (isNotFromSelf(deleteEvent)) {
return;
}
sendDeleteMessage(deleteEvent.getTenant(), deleteEvent.getControllerId(), deleteEvent.getTargetAddress());
}
void sendDeleteMessage(final String tenant, final String controllerId, final String targetAddress) {
if (!hasValidAddress(targetAddress)) { if (!hasValidAddress(targetAddress)) {
return; return;
@@ -206,7 +212,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
return serviceMatcher != null && !serviceMatcher.isFromSelf(event); return serviceMatcher != null && !serviceMatcher.isFromSelf(event);
} }
void sendCancelMessageToTarget(final String tenant, final String controllerId, final Long actionId, protected void sendCancelMessageToTarget(final String tenant, final String controllerId, final Long actionId,
final URI address) { final URI address) {
if (!IpUtil.isAmqpUri(address)) { if (!IpUtil.isAmqpUri(address)) {
return; return;

View File

@@ -28,8 +28,6 @@ import org.eclipse.hawkbit.cache.DownloadIdCache;
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;
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse; import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.SystemManagement;
@@ -42,7 +40,9 @@ 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.repository.model.TenantMetaData; import org.eclipse.hawkbit.repository.model.TenantMetaData;
import org.eclipse.hawkbit.security.DdiSecurityProperties; import org.eclipse.hawkbit.security.DdiSecurityProperties;
import org.eclipse.hawkbit.security.DmfTenantSecurityToken;
import org.eclipse.hawkbit.security.DdiSecurityProperties.Authentication.Anonymous; import org.eclipse.hawkbit.security.DdiSecurityProperties.Authentication.Anonymous;
import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.security.DdiSecurityProperties.Rp; import org.eclipse.hawkbit.security.DdiSecurityProperties.Rp;
import org.eclipse.hawkbit.security.SecurityContextTenantAware; import org.eclipse.hawkbit.security.SecurityContextTenantAware;
import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.security.SystemSecurityContext;

View File

@@ -108,28 +108,14 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
when(systemManagement.getTenantMetadata()).thenReturn(tenantMetaData); when(systemManagement.getTenantMetadata()).thenReturn(tenantMetaData);
amqpMessageDispatcherService = new AmqpMessageDispatcherService(rabbitTemplate, senderService, amqpMessageDispatcherService = new AmqpMessageDispatcherService(rabbitTemplate, senderService,
artifactUrlHandlerMock, systemSecurityContext, systemManagement, targetManagement, serviceMatcher); artifactUrlHandlerMock, systemSecurityContext, systemManagement, targetManagement, serviceMatcher,
distributionSetManagement);
} }
@Test
@Description("Verifies that download and install event with no software modul works")
public void testSendDownloadRequesWithEmptySoftwareModules() {
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
"DEFAULT", 1L, 1L, CONTROLLER_ID, serviceMatcher.getServiceId());
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
final Message sendMessage = getCaptureAdressEvent(targetAssignDistributionSetEvent);
final DmfDownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage, 1L);
assertThat(downloadAndUpdateRequest.getTargetSecurityToken()).isEqualTo(TEST_TOKEN);
assertTrue("No softwaremmodule should be contained in the request",
downloadAndUpdateRequest.getSoftwareModules().isEmpty());
}
private Message getCaptureAdressEvent(final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent) { private Message getCaptureAdressEvent(final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent) {
final Target target = targetManagement.getByControllerID(targetAssignDistributionSetEvent.getControllerId()) final Target target = targetManagement
.get(); .getByControllerID(targetAssignDistributionSetEvent.getActions().keySet().iterator().next()).get();
final Message sendMessage = createArgumentCapture(target.getAddress()); final Message sendMessage = createArgumentCapture(target.getAddress());
return sendMessage; return sendMessage;
} }

View File

@@ -28,8 +28,6 @@ import java.util.Optional;
import org.eclipse.hawkbit.api.HostnameResolver; import org.eclipse.hawkbit.api.HostnameResolver;
import org.eclipse.hawkbit.artifact.repository.ArtifactRepository; import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
import org.eclipse.hawkbit.cache.DownloadIdCache; import org.eclipse.hawkbit.cache.DownloadIdCache;
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;
@@ -38,8 +36,6 @@ import org.eclipse.hawkbit.dmf.json.model.DmfActionStatus;
import org.eclipse.hawkbit.dmf.json.model.DmfActionUpdateStatus; import org.eclipse.hawkbit.dmf.json.model.DmfActionUpdateStatus;
import org.eclipse.hawkbit.dmf.json.model.DmfAttributeUpdate; import org.eclipse.hawkbit.dmf.json.model.DmfAttributeUpdate;
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse; import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.EntityFactory;
@@ -52,6 +48,8 @@ import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.Artifact; import org.eclipse.hawkbit.repository.model.Artifact;
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.security.DmfTenantSecurityToken;
import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.security.SecurityTokenGenerator;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.junit.Before; import org.junit.Before;
@@ -370,15 +368,12 @@ public class AmqpMessageHandlerServiceTest {
// mock // mock
final Artifact localArtifactMock = mock(Artifact.class); final Artifact localArtifactMock = mock(Artifact.class);
when(localArtifactMock.getSha1Hash()).thenReturn(SHA1); when(localArtifactMock.getSha1Hash()).thenReturn(SHA1);
when(localArtifactMock.getMd5Hash()).thenReturn("md5");
when(localArtifactMock.getSize()).thenReturn(1L);
final AbstractDbArtifact dbArtifactMock = mock(AbstractDbArtifact.class);
when(artifactManagementMock.findFirstBySHA1(SHA1)).thenReturn(Optional.of(localArtifactMock)); when(artifactManagementMock.findFirstBySHA1(SHA1)).thenReturn(Optional.of(localArtifactMock));
when(controllerManagementMock.hasTargetArtifactAssigned(securityToken.getControllerId(), SHA1)) when(controllerManagementMock.hasTargetArtifactAssigned(securityToken.getControllerId(), SHA1))
.thenReturn(true); .thenReturn(true);
when(artifactManagementMock.loadArtifactBinary(anyString())).thenReturn(Optional.of(dbArtifactMock));
when(dbArtifactMock.getArtifactId()).thenReturn("artifactId");
when(dbArtifactMock.getSize()).thenReturn(1L);
when(dbArtifactMock.getHashes()).thenReturn(new DbArtifactHash(SHA1, "md5"));
when(hostnameResolverMock.resolveHostname()).thenReturn(new URL("http://localhost")); when(hostnameResolverMock.resolveHostname()).thenReturn(new URL("http://localhost"));
// test // test

View File

@@ -18,8 +18,6 @@ import org.eclipse.hawkbit.amqp.AmqpProperties;
import org.eclipse.hawkbit.amqp.DmfApiConfiguration; import org.eclipse.hawkbit.amqp.DmfApiConfiguration;
import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings; import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings;
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse; import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.rabbitmq.test.AbstractAmqpIntegrationTest; import org.eclipse.hawkbit.rabbitmq.test.AbstractAmqpIntegrationTest;
import org.eclipse.hawkbit.rabbitmq.test.AmqpTestConfiguration; import org.eclipse.hawkbit.rabbitmq.test.AmqpTestConfiguration;
import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration; import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration;
@@ -28,6 +26,8 @@ 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.TargetWithActionType; import org.eclipse.hawkbit.repository.model.TargetWithActionType;
import org.eclipse.hawkbit.security.DmfTenantSecurityToken;
import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;

View File

@@ -21,9 +21,8 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@@ -407,7 +407,8 @@ public interface DeploymentManagement {
* @return the amount of started actions * @return the amount of started actions
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long startScheduledActionsByRolloutGroupParent(@NotNull Long rolloutId, Long rolloutGroupParentId); long startScheduledActionsByRolloutGroupParent(@NotNull Long rolloutId, @NotNull Long distributionSetId,
Long rolloutGroupParentId);
/** /**
* All {@link ActionStatus} entries in the repository. * All {@link ActionStatus} entries in the repository.

View File

@@ -8,15 +8,13 @@
*/ */
package org.eclipse.hawkbit.repository.event.remote; package org.eclipse.hawkbit.repository.event.remote;
import java.util.Collection; import java.util.Arrays;
import java.util.Collections; import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
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.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import com.fasterxml.jackson.annotation.JsonIgnore;
/** /**
* TenantAwareEvent that gets sent when a distribution set gets assigned to a * TenantAwareEvent that gets sent when a distribution set gets assigned to a
@@ -26,13 +24,9 @@ public class TargetAssignDistributionSetEvent extends RemoteTenantAwareEvent {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private Long actionId; private long distributionSetId;
private Long distributionSetId; private final Map<String, Long> actions = new HashMap<>();
private String controllerId;
private transient Collection<SoftwareModule> modules;
/** /**
* Default constructor. * Default constructor.
@@ -44,60 +38,34 @@ public class TargetAssignDistributionSetEvent extends RemoteTenantAwareEvent {
/** /**
* Constructor. * Constructor.
* *
* @param action * @param tenant
* the action * of the event
* @param distributionSetId
* of the set that was assigned
* @param a
* the actions and the targets
* @param applicationId * @param applicationId
* the application id. * the application id.
*/ */
public TargetAssignDistributionSetEvent(final Action action, final String applicationId) { public TargetAssignDistributionSetEvent(final String tenant, final long distributionSetId, final List<Action> a,
this(action.getTenant(), action.getId(), action.getDistributionSet().getId(), final String applicationId) {
action.getTarget().getControllerId(), applicationId); super(distributionSetId, tenant, applicationId);
this.modules = action.getDistributionSet().getModules();
}
/**
* Constructor.
*
* @param tenant
* the event belongs to
* @param actionId
* to the action
* @param distributionSetId
* of the assigned {@link DistributionSet}
* @param controllerId
* of the assignment {@link Target}
* @param applicationId
*/
public TargetAssignDistributionSetEvent(final String tenant, final Long actionId, final Long distributionSetId,
final String controllerId, final String applicationId) {
super(actionId, tenant, applicationId);
this.actionId = actionId;
this.distributionSetId = distributionSetId; this.distributionSetId = distributionSetId;
this.controllerId = controllerId; actions.putAll(a.stream().filter(action -> action.getDistributionSet().getId().longValue() == distributionSetId)
.collect(Collectors.toMap(action -> action.getTarget().getControllerId(), Action::getId)));
} }
public Long getActionId() { public TargetAssignDistributionSetEvent(final Action action, final String applicationId) {
return actionId; this(action.getTenant(), action.getDistributionSet().getId(), Arrays.asList(action), applicationId);
}
public String getControllerId() {
return controllerId;
} }
public Long getDistributionSetId() { public Long getDistributionSetId() {
return distributionSetId; return distributionSetId;
} }
/** public Map<String, Long> getActions() {
* @return modules if Event has been published by same node otherwise empty. return actions;
*/
@JsonIgnore
public Collection<SoftwareModule> getModules() {
if (modules == null) {
return Collections.emptyList();
} }
return modules;
}
} }

View File

@@ -19,7 +19,6 @@ import org.springframework.util.MimeType;
import io.protostuff.LinkedBuffer; import io.protostuff.LinkedBuffer;
import io.protostuff.ProtobufIOUtil; import io.protostuff.ProtobufIOUtil;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema; import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema; import io.protostuff.runtime.RuntimeSchema;
@@ -127,7 +126,7 @@ public class BusProtoStuffMessageConverter extends AbstractMessageConverter {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final Schema<Object> schema = (Schema<Object>) RuntimeSchema.getSchema(serializeClass); final Schema<Object> schema = (Schema<Object>) RuntimeSchema.getSchema(serializeClass);
final LinkedBuffer buffer = LinkedBuffer.allocate(); final LinkedBuffer buffer = LinkedBuffer.allocate();
return writeProtoBuf(payload, schema, buffer); return ProtobufIOUtil.toByteArray(payload, schema, buffer);
} }
private static byte[] writeClassHeader(final Class<?> clazz) { private static byte[] writeClassHeader(final Class<?> clazz) {
@@ -140,17 +139,6 @@ public class BusProtoStuffMessageConverter extends AbstractMessageConverter {
final Schema<Object> schema = (Schema<Object>) RuntimeSchema final Schema<Object> schema = (Schema<Object>) RuntimeSchema
.getSchema((Class<? extends Object>) EventType.class); .getSchema((Class<? extends Object>) EventType.class);
final LinkedBuffer buffer = LinkedBuffer.allocate(); final LinkedBuffer buffer = LinkedBuffer.allocate();
return writeProtoBuf(clazzEventType, schema, buffer); return ProtobufIOUtil.toByteArray(clazzEventType, schema, buffer);
}
private static byte[] writeProtoBuf(final Object payload, final Schema<Object> schema, final LinkedBuffer buffer) {
final byte[] serializeByte;
try {
serializeByte = ProtostuffIOUtil.toByteArray(payload, schema, buffer);
} finally {
buffer.clear();
}
return serializeByte;
} }
} }

View File

@@ -31,6 +31,7 @@ import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetWithActionType; import org.eclipse.hawkbit.repository.model.TargetWithActionType;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.util.CollectionUtils;
/** /**
* {@link DistributionSet} to {@link Target} assignment strategy as utility for * {@link DistributionSet} to {@link Target} assignment strategy as utility for
@@ -109,6 +110,8 @@ public abstract class AbstractDsAssignmentStrategy {
/** /**
* Handles event sending related to the assignment. * Handles event sending related to the assignment.
* *
* @param set
* that has been assigned
* @param targets * @param targets
* to send events for * to send events for
* @param targetIdsCancelList * @param targetIdsCancelList
@@ -117,12 +120,17 @@ public abstract class AbstractDsAssignmentStrategy {
* mapping of {@link Target#getControllerId()} to new * mapping of {@link Target#getControllerId()} to new
* {@link Action} that was created as part of the assignment. * {@link Action} that was created as part of the assignment.
*/ */
abstract void sendAssignmentEvents(final List<JpaTarget> targets, final Set<Long> targetIdsCancelList, abstract void sendAssignmentEvents(DistributionSet set, final List<JpaTarget> targets,
final Map<String, JpaAction> controllerIdsToActions); final Set<Long> targetIdsCancelList, final Map<String, JpaAction> controllerIdsToActions);
protected void sendTargetAssignDistributionSetEvent(final Action action) { protected void sendTargetAssignDistributionSetEvent(final String tenant, final long distributionSetId,
afterCommit.afterCommit(() -> eventPublisher final List<Action> actions) {
.publishEvent(new TargetAssignDistributionSetEvent(action, applicationContext.getId()))); if (CollectionUtils.isEmpty(actions)) {
return;
}
afterCommit.afterCommit(() -> eventPublisher.publishEvent(
new TargetAssignDistributionSetEvent(tenant, distributionSetId, actions, applicationContext.getId())));
} }
protected void sendTargetUpdatedEvent(final JpaTarget target) { protected void sendTargetUpdatedEvent(final JpaTarget target) {

View File

@@ -13,6 +13,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
@@ -24,7 +25,6 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.JoinType; import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.ListJoin; import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.ActionFields; import org.eclipse.hawkbit.repository.ActionFields;
import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DeploymentManagement;
@@ -80,6 +80,7 @@ import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@@ -306,7 +307,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
// detaching as the entity has been updated by the JPQL query above // detaching as the entity has been updated by the JPQL query above
targets.forEach(entityManager::detach); targets.forEach(entityManager::detach);
assignmentStrategy.sendAssignmentEvents(targets, targetIdsCancellList, targetIdsToActions); assignmentStrategy.sendAssignmentEvents(set, targets, targetIdsCancellList, targetIdsToActions);
return new DistributionSetAssignmentResult( return new DistributionSetAssignmentResult(
targets.stream().map(Target::getControllerId).collect(Collectors.toList()), targets.size(), targets.stream().map(Target::getControllerId).collect(Collectors.toList()), targets.size(),
@@ -373,13 +374,13 @@ public class JpaDeploymentManagement implements DeploymentManagement {
} }
@Override @Override
public long startScheduledActionsByRolloutGroupParent(@NotNull final Long rolloutId, public long startScheduledActionsByRolloutGroupParent(final Long rolloutId, final Long distributionSetId,
final Long rolloutGroupParentId) { final Long rolloutGroupParentId) {
long totalActionsCount = 0L; long totalActionsCount = 0L;
long lastStartedActionsCount; long lastStartedActionsCount;
do { do {
lastStartedActionsCount = startScheduledActionsByRolloutGroupParentInNewTransaction(rolloutId, lastStartedActionsCount = startScheduledActionsByRolloutGroupParentInNewTransaction(rolloutId,
rolloutGroupParentId, ACTION_PAGE_LIMIT); distributionSetId, rolloutGroupParentId, ACTION_PAGE_LIMIT);
totalActionsCount += lastStartedActionsCount; totalActionsCount += lastStartedActionsCount;
} while (lastStartedActionsCount > 0); } while (lastStartedActionsCount > 0);
@@ -387,7 +388,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
} }
private long startScheduledActionsByRolloutGroupParentInNewTransaction(final Long rolloutId, private long startScheduledActionsByRolloutGroupParentInNewTransaction(final Long rolloutId,
final Long rolloutGroupParentId, final int limit) { final Long distributionSetId, final Long rolloutGroupParentId, final int limit) {
final DefaultTransactionDefinition def = new DefaultTransactionDefinition(); final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("startScheduledActions-" + rolloutId); def.setName("startScheduledActions-" + rolloutId);
def.setReadOnly(false); def.setReadOnly(false);
@@ -396,7 +397,21 @@ public class JpaDeploymentManagement implements DeploymentManagement {
final Page<Action> rolloutGroupActions = findActionsByRolloutAndRolloutGroupParent(rolloutId, final Page<Action> rolloutGroupActions = findActionsByRolloutAndRolloutGroupParent(rolloutId,
rolloutGroupParentId, limit); rolloutGroupParentId, limit);
rolloutGroupActions.map(action -> (JpaAction) action).forEach(this::startScheduledAction); if (rolloutGroupActions.getContent().isEmpty()) {
return 0L;
}
final String tenant = rolloutGroupActions.getContent().get(0).getTenant();
final List<Action> targetAssignments = rolloutGroupActions.getContent().stream()
.map(action -> (JpaAction) action).map(this::closeActionIfSetWasAlreadyAssigned)
.filter(Objects::nonNull).map(this::startScheduledActionIfNoCancelationHasToBeHandledFirst)
.filter(Objects::nonNull).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(targetAssignments)) {
afterCommit.afterCommit(() -> eventPublisher.publishEvent(new TargetAssignDistributionSetEvent(tenant,
distributionSetId, targetAssignments, applicationContext.getId())));
}
return rolloutGroupActions.getTotalElements(); return rolloutGroupActions.getTotalElements();
}); });
@@ -415,9 +430,8 @@ public class JpaDeploymentManagement implements DeploymentManagement {
} }
} }
private void startScheduledAction(final JpaAction action) { private JpaAction closeActionIfSetWasAlreadyAssigned(final JpaAction action) {
JpaTarget target = (JpaTarget) action.getTarget(); final JpaTarget target = (JpaTarget) action.getTarget();
if (target.getAssignedDistributionSet() != null if (target.getAssignedDistributionSet() != null
&& action.getDistributionSet().getId().equals(target.getAssignedDistributionSet().getId())) { && action.getDistributionSet().getId().equals(target.getAssignedDistributionSet().getId())) {
// the target has already the distribution set assigned, we don't // the target has already the distribution set assigned, we don't
@@ -426,9 +440,13 @@ public class JpaDeploymentManagement implements DeploymentManagement {
action.setActive(false); action.setActive(false);
setSkipActionStatus(action); setSkipActionStatus(action);
actionRepository.save(action); actionRepository.save(action);
return; return null;
} }
return action;
}
private JpaAction startScheduledActionIfNoCancelationHasToBeHandledFirst(final JpaAction action) {
// check if we need to override running update actions // check if we need to override running update actions
final List<Long> overrideObsoleteUpdateActions = onlineDsAssignmentStrategy final List<Long> overrideObsoleteUpdateActions = onlineDsAssignmentStrategy
.overrideObsoleteUpdateActions(Collections.singletonList(action.getTarget().getId())); .overrideObsoleteUpdateActions(Collections.singletonList(action.getTarget().getId()));
@@ -439,7 +457,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
actionStatusRepository.save(onlineDsAssignmentStrategy.createActionStatus(savedAction, null)); actionStatusRepository.save(onlineDsAssignmentStrategy.createActionStatus(savedAction, null));
target = (JpaTarget) entityManager.merge(savedAction.getTarget()); final JpaTarget target = (JpaTarget) entityManager.merge(savedAction.getTarget());
target.setAssignedDistributionSet(savedAction.getDistributionSet()); target.setAssignedDistributionSet(savedAction.getDistributionSet());
target.setUpdateStatus(TargetUpdateStatus.PENDING); target.setUpdateStatus(TargetUpdateStatus.PENDING);
@@ -447,10 +465,11 @@ public class JpaDeploymentManagement implements DeploymentManagement {
// in case we canceled an action before for this target, then don't fire // in case we canceled an action before for this target, then don't fire
// assignment event // assignment event
if (!overrideObsoleteUpdateActions.contains(savedAction.getId())) { if (overrideObsoleteUpdateActions.contains(savedAction.getId())) {
afterCommit.afterCommit(() -> eventPublisher return null;
.publishEvent(new TargetAssignDistributionSetEvent(savedAction, applicationContext.getId())));
} }
return savedAction;
} }
private void setSkipActionStatus(final JpaAction action) { private void setSkipActionStatus(final JpaAction action) {

View File

@@ -367,8 +367,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
RolloutGroupStatus.READY, group); RolloutGroupStatus.READY, group);
final long targetsInGroupFilter = runInNewTransaction("countAllTargetsByTargetFilterQueryAndNotInRolloutGroups", final long targetsInGroupFilter = runInNewTransaction("countAllTargetsByTargetFilterQueryAndNotInRolloutGroups",
count -> targetManagement.countByRsqlAndNotInRolloutGroups(readyGroups, count -> targetManagement.countByRsqlAndNotInRolloutGroups(readyGroups, groupTargetFilter));
groupTargetFilter));
final long expectedInGroup = Math.round(group.getTargetPercentage() / 100 * (double) targetsInGroupFilter); final long expectedInGroup = Math.round(group.getTargetPercentage() / 100 * (double) targetsInGroupFilter);
final long currentlyInGroup = runInNewTransaction("countRolloutTargetGroupByRolloutGroup", final long currentlyInGroup = runInNewTransaction("countRolloutTargetGroupByRolloutGroup",
count -> rolloutTargetGroupRepository.countByRolloutGroup(group)); count -> rolloutTargetGroupRepository.countByRolloutGroup(group));
@@ -408,8 +407,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
final PageRequest pageRequest = new PageRequest(0, Math.toIntExact(limit)); final PageRequest pageRequest = new PageRequest(0, Math.toIntExact(limit));
final List<Long> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout.getRolloutGroups(), final List<Long> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout.getRolloutGroups(),
RolloutGroupStatus.READY, group); RolloutGroupStatus.READY, group);
final Page<Target> targets = targetManagement final Page<Target> targets = targetManagement.findByTargetFilterQueryAndNotInRolloutGroups(pageRequest,
.findByTargetFilterQueryAndNotInRolloutGroups(pageRequest, readyGroups, targetFilter); readyGroups, targetFilter);
createAssignmentOfTargetsToGroup(targets, group); createAssignmentOfTargetsToGroup(targets, group);
@@ -461,7 +460,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
throw new RolloutIllegalStateException("First Group is not the first group."); throw new RolloutIllegalStateException("First Group is not the first group.");
} }
deploymentManagement.startScheduledActionsByRolloutGroupParent(rollout.getId(), null); deploymentManagement.startScheduledActionsByRolloutGroupParent(rollout.getId(),
rollout.getDistributionSet().getId(), null);
rolloutGroup.setStatus(RolloutGroupStatus.RUNNING); rolloutGroup.setStatus(RolloutGroupStatus.RUNNING);
rolloutGroupRepository.save(rolloutGroup); rolloutGroupRepository.save(rolloutGroup);
@@ -530,8 +530,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
final ActionType actionType = rollout.getActionType(); final ActionType actionType = rollout.getActionType();
final long forceTime = rollout.getForcedTime(); final long forceTime = rollout.getForcedTime();
final Page<Target> targets = targetManagement.findByInRolloutGroupWithoutAction(pageRequest, final Page<Target> targets = targetManagement.findByInRolloutGroupWithoutAction(pageRequest, groupId);
groupId);
if (targets.getTotalElements() > 0) { if (targets.getTotalElements() > 0) {
createScheduledAction(targets.getContent(), distributionSet, actionType, forceTime, rollout, group); createScheduledAction(targets.getContent(), distributionSet, actionType, forceTime, rollout, group);
} }

View File

@@ -25,6 +25,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications; import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.TargetWithActionType; import org.eclipse.hawkbit.repository.model.TargetWithActionType;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@@ -48,8 +49,8 @@ public class OfflineDsAssignmentStrategy extends AbstractDsAssignmentStrategy {
} }
@Override @Override
void sendAssignmentEvents(final List<JpaTarget> targets, final Set<Long> targetIdsCancellList, void sendAssignmentEvents(final DistributionSet set, final List<JpaTarget> targets,
final Map<String, JpaAction> targetIdsToActions) { final Set<Long> targetIdsCancellList, final Map<String, JpaAction> targetIdsToActions) {
targets.forEach(target -> { targets.forEach(target -> {
target.setUpdateStatus(TargetUpdateStatus.IN_SYNC); target.setUpdateStatus(TargetUpdateStatus.IN_SYNC);

View File

@@ -21,7 +21,10 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications; import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet;
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.model.TargetWithActionType; import org.eclipse.hawkbit.repository.model.TargetWithActionType;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@@ -44,18 +47,19 @@ public class OnlineDsAssignmentStrategy extends AbstractDsAssignmentStrategy {
} }
@Override @Override
void sendAssignmentEvents(final List<JpaTarget> targets, final Set<Long> targetIdsCancellList, void sendAssignmentEvents(final DistributionSet set, final List<JpaTarget> targets,
final Map<String, JpaAction> targetIdsToActions) { final Set<Long> targetIdsCancellList, final Map<String, JpaAction> targetIdsToActions) {
targets.forEach(target -> { final List<Action> actions = targets.stream().map(target -> {
target.setUpdateStatus(TargetUpdateStatus.PENDING); target.setUpdateStatus(TargetUpdateStatus.PENDING);
sendTargetUpdatedEvent(target); sendTargetUpdatedEvent(target);
if (targetIdsCancellList.contains(target.getId())) {
return;
}
sendTargetAssignDistributionSetEvent(targetIdsToActions.get(target.getControllerId())); return target;
}); }).filter(target -> !targetIdsCancellList.contains(target.getId())).map(Target::getControllerId)
.map(targetIdsToActions::get).collect(Collectors.toList());
sendTargetAssignDistributionSetEvent(set.getTenant(), set.getId(), actions);
} }
@Override @Override

View File

@@ -56,8 +56,8 @@ public class StartNextGroupRolloutGroupSuccessAction implements RolloutGroupActi
// retrieve all actions according to the parent group of the finished // retrieve all actions according to the parent group of the finished
// rolloutGroup, so retrieve all child-group actions which need to be // rolloutGroup, so retrieve all child-group actions which need to be
// started. // started.
final long countOfStartedActions = deploymentManagement final long countOfStartedActions = deploymentManagement.startScheduledActionsByRolloutGroupParent(
.startScheduledActionsByRolloutGroupParent(rollout.getId(), rolloutGroup.getId()); rollout.getId(), rollout.getDistributionSet().getId(), rolloutGroup.getId());
logger.debug("{} Next actions started for rollout {} and parent group {}", countOfStartedActions, rollout, logger.debug("{} Next actions started for rollout {} and parent group {}", countOfStartedActions, rollout,
rolloutGroup); rolloutGroup);
if (countOfStartedActions > 0) { if (countOfStartedActions > 0) {

View File

@@ -10,6 +10,10 @@ package org.eclipse.hawkbit.repository.event.remote;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Arrays;
import java.util.Map.Entry;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
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;
@@ -50,8 +54,8 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
generateAction.setStatus(Status.RUNNING); generateAction.setStatus(Status.RUNNING);
final Action action = actionRepository.save(generateAction); final Action action = actionRepository.save(generateAction);
final TargetAssignDistributionSetEvent assignmentEvent = new TargetAssignDistributionSetEvent(action, final TargetAssignDistributionSetEvent assignmentEvent = new TargetAssignDistributionSetEvent(
serviceMatcher.getServiceId()); action.getTenant(), dsA.getId(), Arrays.asList(action), serviceMatcher.getServiceId());
TargetAssignDistributionSetEvent underTest = (TargetAssignDistributionSetEvent) createProtoStuffEvent( TargetAssignDistributionSetEvent underTest = (TargetAssignDistributionSetEvent) createProtoStuffEvent(
assignmentEvent); assignmentEvent);
@@ -63,12 +67,11 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
private void assertTargetAssignDistributionSetEvent(final Action action, private void assertTargetAssignDistributionSetEvent(final Action action,
final TargetAssignDistributionSetEvent underTest) { final TargetAssignDistributionSetEvent underTest) {
assertThat(underTest.getActionId()).isNotNull();
assertThat(underTest.getControllerId()).isNotNull();
assertThat(underTest.getDistributionSetId()).isNotNull();
assertThat(underTest.getActionId()).isEqualTo(action.getId()); final Entry<String, Long> entry = new SimpleImmutableEntry(action.getTarget().getControllerId(),
assertThat(underTest.getControllerId()).isEqualTo(action.getTarget().getControllerId()); action.getId());
assertThat(underTest.getActions()).containsExactly(entry);
assertThat(underTest.getDistributionSetId()).isEqualTo(action.getDistributionSet().getId()); assertThat(underTest.getDistributionSetId()).isEqualTo(action.getDistributionSet().getId());
} }

View File

@@ -237,7 +237,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Description("Test verifies that an assignment with automatic cancelation works correctly even if the update is split into multiple partitions on the database.") @Description("Test verifies that an assignment with automatic cancelation works correctly even if the update is split into multiple partitions on the database.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10), @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10),
@Expect(type = TargetUpdatedEvent.class, count = 2 * (Constants.MAX_ENTRIES_IN_STATEMENT + 10)), @Expect(type = TargetUpdatedEvent.class, count = 2 * (Constants.MAX_ENTRIES_IN_STATEMENT + 10)),
@Expect(type = TargetAssignDistributionSetEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 2 * (Constants.MAX_ENTRIES_IN_STATEMENT + 10)), @Expect(type = ActionCreatedEvent.class, count = 2 * (Constants.MAX_ENTRIES_IN_STATEMENT + 10)),
@Expect(type = CancelTargetAssignmentEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10), @Expect(type = CancelTargetAssignmentEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10),
@Expect(type = ActionUpdatedEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10), @Expect(type = ActionUpdatedEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10),
@@ -437,7 +437,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetUpdatedEvent.class, count = 20), @Expect(type = ActionCreatedEvent.class, count = 20), @Expect(type = TargetUpdatedEvent.class, count = 20), @Expect(type = ActionCreatedEvent.class, count = 20),
@Expect(type = DistributionSetCreatedEvent.class, count = 2), @Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6), @Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 10) }) @Expect(type = TargetAssignDistributionSetEvent.class, count = 1) })
public void assignedDistributionSet() { public void assignedDistributionSet() {
final List<String> controllerIds = testdataFactory.createTargets(10).stream().map(Target::getControllerId) final List<String> controllerIds = testdataFactory.createTargets(10).stream().map(Target::getControllerId)
.collect(Collectors.toList()); .collect(Collectors.toList());
@@ -468,7 +468,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = ActionUpdatedEvent.class, count = 10), @Expect(type = ActionUpdatedEvent.class, count = 10),
@Expect(type = DistributionSetCreatedEvent.class, count = 2), @Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6), @Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 20) }) @Expect(type = TargetAssignDistributionSetEvent.class, count = 2) })
public void assigneDistributionSetAndAutoCloseActiveActions() { public void assigneDistributionSetAndAutoCloseActiveActions() {
tenantConfigurationManagement tenantConfigurationManagement
.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true); .addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
@@ -517,7 +517,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
@Description("Simple deployment or distribution set to target assignment test.") @Description("Simple deployment or distribution set to target assignment test.")
public void assignDistributionSet2Targets() throws InterruptedException { public void assignDistributionSet2Targets() throws InterruptedException {
eventHandlerStub.setExpectedNumberOfEvents(20); eventHandlerStub.setExpectedNumberOfEvents(1);
final String myCtrlIDPref = "myCtrlID"; final String myCtrlIDPref = "myCtrlID";
final Iterable<Target> savedNakedTargets = testdataFactory.createTargets(10, myCtrlIDPref, "first description"); final Iterable<Target> savedNakedTargets = testdataFactory.createTargets(10, myCtrlIDPref, "first description");
@@ -595,7 +595,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final DistributionSet nowComplete = distributionSetManagement.assignSoftwareModules(incomplete.getId(), final DistributionSet nowComplete = distributionSetManagement.assignSoftwareModules(incomplete.getId(),
Sets.newHashSet(os.getId())); Sets.newHashSet(os.getId()));
eventHandlerStub.setExpectedNumberOfEvents(10); eventHandlerStub.setExpectedNumberOfEvents(1);
assertThat(assignDistributionSet(nowComplete, targets).getAssigned()).as("assign ds doesn't work") assertThat(assignDistributionSet(nowComplete, targets).getAssigned()).as("assign ds doesn't work")
.isEqualTo(10); .isEqualTo(10);
@@ -606,6 +606,14 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
@Description("Multiple deployments or distribution set to target assignment test. Expected behaviour is that a new deployment " @Description("Multiple deployments or distribution set to target assignment test. Expected behaviour is that a new deployment "
+ "overides unfinished old one which are canceled as part of the operation.") + "overides unfinished old one which are canceled as part of the operation.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 5 + 4),
@Expect(type = TargetUpdatedEvent.class, count = 3 * 4),
@Expect(type = ActionCreatedEvent.class, count = 3 * 4),
@Expect(type = ActionUpdatedEvent.class, count = 4 * 2),
@Expect(type = CancelTargetAssignmentEvent.class, count = 4 * 2),
@Expect(type = DistributionSetCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 9),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1) })
public void mutipleDeployments() throws InterruptedException { public void mutipleDeployments() throws InterruptedException {
final String undeployedTargetPrefix = "undep-T"; final String undeployedTargetPrefix = "undep-T";
final int noOfUndeployedTargets = 5; final int noOfUndeployedTargets = 5;
@@ -615,8 +623,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final int noOfDistributionSets = 3; final int noOfDistributionSets = 3;
// Each of the four targets get one assignment (4 * 1 = 4) // One assigment per DS
final int expectedNumberOfEventsForAssignment = 4; final int expectedNumberOfEventsForAssignment = 1;
eventHandlerStub.setExpectedNumberOfEvents(expectedNumberOfEventsForAssignment); eventHandlerStub.setExpectedNumberOfEvents(expectedNumberOfEventsForAssignment);
// Each of the four targets get two more assignment the which are // Each of the four targets get two more assignment the which are
@@ -641,10 +649,10 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
// only records retrieved from the DB can be evaluated to be sure that // only records retrieved from the DB can be evaluated to be sure that
// all fields are // all fields are
// populated; // populated;
final Iterable<JpaTarget> allFoundTargets = targetRepository.findAll(); final List<JpaTarget> allFoundTargets = targetRepository.findAll();
final Iterable<JpaTarget> deployedTargetsFromDB = targetRepository.findAll(deployedTargetIDs); final List<JpaTarget> deployedTargetsFromDB = targetRepository.findAll(deployedTargetIDs);
final Iterable<JpaTarget> undeployedTargetsFromDB = targetRepository.findAll(undeployedTargetIDs); final List<JpaTarget> undeployedTargetsFromDB = targetRepository.findAll(undeployedTargetIDs);
// test that number of Targets // test that number of Targets
assertThat(allFoundTargets.spliterator().getExactSizeIfKnown()).as("number of target is wrong") assertThat(allFoundTargets.spliterator().getExactSizeIfKnown()).as("number of target is wrong")
@@ -1029,33 +1037,23 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
deployedTargets = assignDistributionSet(ds, deployedTargets).getAssignedEntity(); deployedTargets = assignDistributionSet(ds, deployedTargets).getAssignedEntity();
} }
final DeploymentResult deploymentResult = new DeploymentResult(deployedTargets, nakedTargets, dsList, return new DeploymentResult(deployedTargets, nakedTargets, dsList, deployedTargetPrefix, undeployedTargetPrefix,
deployedTargetPrefix, undeployedTargetPrefix, distributionSetPrefix); distributionSetPrefix);
return deploymentResult;
} }
private void assertTargetAssignDistributionSetEvents(final List<Target> targets, final DistributionSet ds, private void assertTargetAssignDistributionSetEvents(final List<Target> targets, final DistributionSet ds,
final List<TargetAssignDistributionSetEvent> events) { final List<TargetAssignDistributionSetEvent> events) {
assertThat(events).isNotEmpty(); assertThat(events).hasSize(1);
for (final Target myt : targets) { final TargetAssignDistributionSetEvent event = events.get(0);
boolean found = false; assertThat(event).isNotNull();
for (final TargetAssignDistributionSetEvent event : events) { assertThat(event.getDistributionSetId()).isEqualTo(ds.getId());
if (event.getControllerId().equals(myt.getControllerId())) {
found = true;
final List<Action> activeActionsByTarget = deploymentManagement
.findActiveActionsByTarget(PAGE, myt.getControllerId()).getContent();
assertThat(activeActionsByTarget).as("size of active actions for target is wrong").isNotEmpty();
assertThat(event.getActionId()).as("Action id in database and event do not match")
.isEqualTo(activeActionsByTarget.get(0).getId());
assertThat(distributionSetManagement.get(event.getDistributionSetId()).get().getModules()) assertThat(event.getActions()).isEqualTo(targets.stream()
.as("softwaremodule size is not correct") .map(target -> deploymentManagement.findActiveActionsByTarget(PAGE, target.getControllerId())
.containsOnly(ds.getModules().toArray(new SoftwareModule[ds.getModules().size()])); .getContent())
} .flatMap(List::stream)
} .collect(Collectors.toMap(action -> action.getTarget().getControllerId(), Action::getId)));
assertThat(found).as("No event found for controller " + myt.getControllerId()).isTrue();
}
} }
private class DeploymentResult { private class DeploymentResult {

View File

@@ -164,8 +164,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
amountOtherTargets, amountGroups, successCondition, errorCondition); amountOtherTargets, amountGroups, successCondition, errorCondition);
// verify the split of the target and targetGroup // verify the split of the target and targetGroup
final Page<RolloutGroup> rolloutGroups = rolloutGroupManagement final Page<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId());
.findByRollout(PAGE, createdRollout.getId());
// we have total of #amountTargetsForRollout in rollouts splitted in // we have total of #amountTargetsForRollout in rollouts splitted in
// group size #groupSize // group size #groupSize
assertThat(rolloutGroups).hasSize(amountGroups); assertThat(rolloutGroups).hasSize(amountGroups);
@@ -183,8 +182,9 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
successCondition, errorCondition); successCondition, errorCondition);
// verify first group is running // verify first group is running
final RolloutGroup firstGroup = rolloutGroupManagement.findByRollout(new OffsetBasedPageRequest(0, 1, new Sort(Direction.ASC, "id")), final RolloutGroup firstGroup = rolloutGroupManagement
createdRollout.getId()).getContent().get(0); .findByRollout(new OffsetBasedPageRequest(0, 1, new Sort(Direction.ASC, "id")), createdRollout.getId())
.getContent().get(0);
assertThat(firstGroup.getStatus()).isEqualTo(RolloutGroupStatus.RUNNING); assertThat(firstGroup.getStatus()).isEqualTo(RolloutGroupStatus.RUNNING);
// verify other groups are scheduled // verify other groups are scheduled
@@ -224,15 +224,17 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
// verify that now the first and the second group are in running state // verify that now the first and the second group are in running state
final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement.findByRollout( final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement
new OffsetBasedPageRequest(0, 2, new Sort(Direction.ASC, "id")), createdRollout.getId()).getContent(); .findByRollout(new OffsetBasedPageRequest(0, 2, new Sort(Direction.ASC, "id")), createdRollout.getId())
.getContent();
runningRolloutGroups.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.RUNNING) runningRolloutGroups.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.RUNNING)
.as("group should be in running state because it should be started but it is in " + group.getStatus() .as("group should be in running state because it should be started but it is in " + group.getStatus()
+ " state")); + " state"));
// verify that the other groups are still in schedule state // verify that the other groups are still in schedule state
final List<RolloutGroup> scheduledRolloutGroups = rolloutGroupManagement.findByRollout( final List<RolloutGroup> scheduledRolloutGroups = rolloutGroupManagement
new OffsetBasedPageRequest(2, 10, new Sort(Direction.ASC, "id")), createdRollout.getId()).getContent(); .findByRollout(new OffsetBasedPageRequest(2, 10, new Sort(Direction.ASC, "id")), createdRollout.getId())
.getContent();
scheduledRolloutGroups.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.SCHEDULED) scheduledRolloutGroups.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.SCHEDULED)
.as("group should be in scheduled state because it should not be started but it is in " .as("group should be in scheduled state because it should not be started but it is in "
+ group.getStatus() + " state")); + group.getStatus() + " state"));
@@ -293,8 +295,9 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Step("Check the status of the rollout groups, second group should be in running status") @Step("Check the status of the rollout groups, second group should be in running status")
private void checkSecondGroupStatusIsRunning(final Rollout createdRollout) { private void checkSecondGroupStatusIsRunning(final Rollout createdRollout) {
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement.findByRollout( final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement
new OffsetBasedPageRequest(0, 10, new Sort(Direction.ASC, "id")), createdRollout.getId()).getContent(); .findByRollout(new OffsetBasedPageRequest(0, 10, new Sort(Direction.ASC, "id")), createdRollout.getId())
.getContent();
assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED); assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.RUNNING); assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.RUNNING);
assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.SCHEDULED); assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.SCHEDULED);
@@ -330,8 +333,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED); assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED); assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED); assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus()) assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus()).isEqualTo(RolloutStatus.FINISHED);
.isEqualTo(RolloutStatus.FINISHED);
} }
@@ -370,8 +372,9 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.PAUSED); assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.PAUSED);
// the first rollout group should be in error state // the first rollout group should be in error state
final List<RolloutGroup> errorGroup = rolloutGroupManagement.findByRollout( final List<RolloutGroup> errorGroup = rolloutGroupManagement
new OffsetBasedPageRequest(0, 1, new Sort(Direction.ASC, "id")), createdRollout.getId()).getContent(); .findByRollout(new OffsetBasedPageRequest(0, 1, new Sort(Direction.ASC, "id")), createdRollout.getId())
.getContent();
assertThat(errorGroup).hasSize(1); assertThat(errorGroup).hasSize(1);
assertThat(errorGroup.get(0).getStatus()).isEqualTo(RolloutGroupStatus.ERROR); assertThat(errorGroup.get(0).getStatus()).isEqualTo(RolloutGroupStatus.ERROR);
@@ -418,15 +421,15 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.resumeRollout(createdRollout.getId()); rolloutManagement.resumeRollout(createdRollout.getId());
// the rollout should be running again // the rollout should be running again
assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus()) assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus()).isEqualTo(RolloutStatus.RUNNING);
.isEqualTo(RolloutStatus.RUNNING);
// checking rollouts again // checking rollouts again
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
// next group should be running again after resuming the rollout // next group should be running again after resuming the rollout
final List<RolloutGroup> resumedGroups = rolloutGroupManagement.findByRollout( final List<RolloutGroup> resumedGroups = rolloutGroupManagement
new OffsetBasedPageRequest(1, 1, new Sort(Direction.ASC, "id")), createdRollout.getId()).getContent(); .findByRollout(new OffsetBasedPageRequest(1, 1, new Sort(Direction.ASC, "id")), createdRollout.getId())
.getContent();
assertThat(resumedGroups).hasSize(1); assertThat(resumedGroups).hasSize(1);
assertThat(resumedGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.RUNNING); assertThat(resumedGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.RUNNING);
} }
@@ -590,8 +593,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
// round(5/2)=3 targets SCHEDULED (Group 3) // round(5/2)=3 targets SCHEDULED (Group 3)
// round(2/1)=2 targets SCHEDULED (Group 4) // round(2/1)=2 targets SCHEDULED (Group 4)
createdRollout = rolloutManagement.get(createdRollout.getId()).get(); createdRollout = rolloutManagement.get(createdRollout.getId()).get();
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId())
.findByRollout(PAGE, createdRollout.getId()).getContent(); .getContent();
Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap(); Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.FINISHED, 2L); expectedTargetCountStatus.put(TotalTargetCountStatus.Status.FINISHED, 2L);
@@ -630,9 +633,10 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(runningActions.size()).isEqualTo(5); assertThat(runningActions.size()).isEqualTo(5);
// 5 targets are in the group and the DS has been assigned // 5 targets are in the group and the DS has been assigned
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId())
.findByRollout(PAGE, createdRollout.getId()).getContent(); .getContent();
final Page<Target> targets = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, rolloutGroups.get(0).getId()); final Page<Target> targets = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE,
rolloutGroups.get(0).getId());
final List<Target> targetList = targets.getContent(); final List<Target> targetList = targets.getContent();
assertThat(targetList.size()).isEqualTo(5); assertThat(targetList.size()).isEqualTo(5);
@@ -769,8 +773,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3); changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
// verify: 40% error but 60% finished -> should move to next group // verify: 40% error but 60% finished -> should move to next group
final List<RolloutGroup> rolloutGruops = rolloutGroupManagement final List<RolloutGroup> rolloutGruops = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId())
.findByRollout(PAGE, rolloutOne.getId()).getContent(); .getContent();
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap(); final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 5L); expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 5L);
validateRolloutGroupActionStatus(rolloutGruops.get(1), expectedTargetCountStatus); validateRolloutGroupActionStatus(rolloutGruops.get(1), expectedTargetCountStatus);
@@ -795,8 +799,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
// verify: 40% error and 60% finished -> should not move to next group // verify: 40% error and 60% finished -> should not move to next group
// because successCondition 80% // because successCondition 80%
final List<RolloutGroup> rolloutGruops = rolloutGroupManagement final List<RolloutGroup> rolloutGruops = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId())
.findByRollout(PAGE, rolloutOne.getId()).getContent(); .getContent();
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap(); final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 5L); expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 5L);
validateRolloutGroupActionStatus(rolloutGruops.get(1), expectedTargetCountStatus); validateRolloutGroupActionStatus(rolloutGruops.get(1), expectedTargetCountStatus);
@@ -868,8 +872,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
changeStatusForAllRunningActions(rolloutD, Status.FINISHED); changeStatusForAllRunningActions(rolloutD, Status.FINISHED);
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
final Page<Rollout> rolloutPage = rolloutManagement.findAllWithDetailedStatus( final Page<Rollout> rolloutPage = rolloutManagement
new OffsetBasedPageRequest(0, 100, new Sort(Direction.ASC, "name")), false); .findAllWithDetailedStatus(new OffsetBasedPageRequest(0, 100, new Sort(Direction.ASC, "name")), false);
final List<Rollout> rolloutList = rolloutPage.getContent(); final List<Rollout> rolloutList = rolloutPage.getContent();
// validate rolloutA -> 6 running and 6 ready // validate rolloutA -> 6 running and 6 ready
@@ -1003,8 +1007,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
myRollout = rolloutManagement.get(myRollout.getId()).get(); myRollout = rolloutManagement.get(myRollout.getId()).get();
float percent = rolloutGroupManagement float percent = rolloutGroupManagement
.getWithDetailedStatus(rolloutGroupManagement .getWithDetailedStatus(
.findByRollout(PAGE, myRollout.getId()).getContent().get(0).getId()) rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent().get(0).getId())
.get().getTotalTargetCountStatus().getFinishedPercent(); .get().getTotalTargetCountStatus().getFinishedPercent();
assertThat(percent).isEqualTo(40); assertThat(percent).isEqualTo(40);
@@ -1012,8 +1016,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
percent = rolloutGroupManagement percent = rolloutGroupManagement
.getWithDetailedStatus(rolloutGroupManagement .getWithDetailedStatus(
.findByRollout(PAGE, myRollout.getId()).getContent().get(0).getId()) rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent().get(0).getId())
.get().getTotalTargetCountStatus().getFinishedPercent(); .get().getTotalTargetCountStatus().getFinishedPercent();
assertThat(percent).isEqualTo(100); assertThat(percent).isEqualTo(100);
@@ -1022,8 +1026,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
percent = rolloutGroupManagement percent = rolloutGroupManagement
.getWithDetailedStatus(rolloutGroupManagement .getWithDetailedStatus(
.findByRollout(PAGE, myRollout.getId()).getContent().get(1).getId()) rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent().get(1).getId())
.get().getTotalTargetCountStatus().getFinishedPercent(); .get().getTotalTargetCountStatus().getFinishedPercent();
assertThat(percent).isEqualTo(80); assertThat(percent).isEqualTo(80);
} }
@@ -1054,25 +1058,25 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
"Target belongs into rollout"); "Target belongs into rollout");
myRollout = rolloutManagement.get(myRollout.getId()).get(); myRollout = rolloutManagement.get(myRollout.getId()).get();
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId())
.findByRollout(PAGE, myRollout.getId()).getContent(); .getContent();
Page<Target> targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100), Page<Target> targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(
rolloutGroups.get(0).getId(), rsqlParam); new OffsetBasedPageRequest(0, 100), rolloutGroups.get(0).getId(), rsqlParam);
final List<Target> targetlistGroup1 = targetPage.getContent(); final List<Target> targetlistGroup1 = targetPage.getContent();
assertThat(targetlistGroup1.size()).isEqualTo(5); assertThat(targetlistGroup1.size()).isEqualTo(5);
assertThat(targetlistGroup1.stream().map(Target::getControllerId).collect(Collectors.toList())) assertThat(targetlistGroup1.stream().map(Target::getControllerId).collect(Collectors.toList()))
.are(targetBelongsInRollout); .are(targetBelongsInRollout);
targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100), rolloutGroups.get(1).getId(), targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100),
rsqlParam); rolloutGroups.get(1).getId(), rsqlParam);
final List<Target> targetlistGroup2 = targetPage.getContent(); final List<Target> targetlistGroup2 = targetPage.getContent();
assertThat(targetlistGroup2.size()).isEqualTo(5); assertThat(targetlistGroup2.size()).isEqualTo(5);
assertThat(targetlistGroup2.stream().map(Target::getControllerId).collect(Collectors.toList())) assertThat(targetlistGroup2.stream().map(Target::getControllerId).collect(Collectors.toList()))
.are(targetBelongsInRollout); .are(targetBelongsInRollout);
targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100), rolloutGroups.get(2).getId(), targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100),
rsqlParam); rolloutGroups.get(2).getId(), rsqlParam);
final List<Target> targetlistGroup3 = targetPage.getContent(); final List<Target> targetlistGroup3 = targetPage.getContent();
assertThat(targetlistGroup3.size()).isEqualTo(5); assertThat(targetlistGroup3.size()).isEqualTo(5);
assertThat(targetlistGroup3.stream().map(Target::getControllerId).collect(Collectors.toList())) assertThat(targetlistGroup3.stream().map(Target::getControllerId).collect(Collectors.toList()))
@@ -1135,8 +1139,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY); assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
final List<RolloutGroup> groups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()) final List<RolloutGroup> groups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent();
.getContent();
assertThat(groups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.READY); assertThat(groups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.READY);
assertThat(groups.get(0).getTotalTargets()).isEqualTo(1); assertThat(groups.get(0).getTotalTargets()).isEqualTo(1);
@@ -1228,8 +1231,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY); assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
// schedule rollout auto start into the future // schedule rollout auto start into the future
rolloutManagement.update( rolloutManagement
entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis() + 60000)); .update(entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis() + 60000));
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
// rollout should not have been started // rollout should not have been started
@@ -1237,8 +1240,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY); assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
// schedule to now // schedule to now
rolloutManagement rolloutManagement.update(entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis()));
.update(entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis()));
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
myRollout = rolloutManagement.get(myRollout.getId()).get(); myRollout = rolloutManagement.get(myRollout.getId()).get();
@@ -1292,8 +1294,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
myRollout = rolloutManagement.get(myRollout.getId()).get(); myRollout = rolloutManagement.get(myRollout.getId()).get();
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.CREATING); assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.CREATING);
for (final RolloutGroup group : rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()) for (final RolloutGroup group : rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent()) {
.getContent()) {
assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.CREATING); assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.CREATING);
} }
@@ -1308,8 +1309,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY); assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
assertThat(myRollout.getTotalTargets()).isEqualTo(amountTargetsInGroup1and2 + amountTargetsInGroup1); assertThat(myRollout.getTotalTargets()).isEqualTo(amountTargetsInGroup1and2 + amountTargetsInGroup1);
final List<RolloutGroup> groups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()) final List<RolloutGroup> groups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent();
.getContent();
; ;
assertThat(groups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.READY); assertThat(groups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.READY);
assertThat(groups.get(0).getTotalTargets()).isEqualTo(amountTargetsInGroup1); assertThat(groups.get(0).getTotalTargets()).isEqualTo(amountTargetsInGroup1);
@@ -1446,7 +1446,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = RolloutUpdatedEvent.class, count = 6), @Expect(type = RolloutUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1), @Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetCreatedEvent.class, count = 25), @Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetCreatedEvent.class, count = 25), @Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = RolloutGroupCreatedEvent.class, count = 5), @Expect(type = RolloutGroupCreatedEvent.class, count = 5),
@Expect(type = RolloutGroupDeletedEvent.class, count = 5), @Expect(type = RolloutGroupDeletedEvent.class, count = 5),
@Expect(type = ActionCreatedEvent.class, count = 10), @Expect(type = ActionUpdatedEvent.class, count = 2), @Expect(type = ActionCreatedEvent.class, count = 10), @Expect(type = ActionUpdatedEvent.class, count = 2),
@@ -1485,8 +1485,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(rolloutManagement.findAll(PAGE, true).getContent()).hasSize(1); assertThat(rolloutManagement.findAll(PAGE, true).getContent()).hasSize(1);
assertThat(rolloutManagement.findAll(PAGE, false).getContent()).hasSize(0); assertThat(rolloutManagement.findAll(PAGE, false).getContent()).hasSize(0);
assertThat(rolloutGroupManagement.findByRolloutWithDetailedStatus(PAGE, createdRollout.getId()) assertThat(rolloutGroupManagement.findByRolloutWithDetailedStatus(PAGE, createdRollout.getId()).getContent())
.getContent()).hasSize(amountGroups); .hasSize(amountGroups);
// verify that all scheduled actions are deleted // verify that all scheduled actions are deleted
assertThat(actionRepository.findByRolloutIdAndStatus(PAGE, deletedRollout.getId(), Status.SCHEDULED) assertThat(actionRepository.findByRolloutIdAndStatus(PAGE, deletedRollout.getId(), Status.SCHEDULED)
@@ -1516,8 +1516,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
private void validateRolloutGroupActionStatus(final RolloutGroup rolloutGroup, private void validateRolloutGroupActionStatus(final RolloutGroup rolloutGroup,
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus) { final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus) {
final RolloutGroup rolloutGroupWithDetail = rolloutGroupManagement final RolloutGroup rolloutGroupWithDetail = rolloutGroupManagement.getWithDetailedStatus(rolloutGroup.getId())
.getWithDetailedStatus(rolloutGroup.getId()).get(); .get();
validateStatus(rolloutGroupWithDetail.getTotalTargetCountStatus(), expectedTargetCountStatus); validateStatus(rolloutGroupWithDetail.getTotalTargetCountStatus(), expectedTargetCountStatus);
} }

View File

@@ -132,8 +132,7 @@ public class EventVerifier extends AbstractTestExecutionListener {
} }
if (event instanceof TargetAssignDistributionSetEvent) { if (event instanceof TargetAssignDistributionSetEvent) {
assertThat(((TargetAssignDistributionSetEvent) event).getActionId()).isNotNull(); assertThat(((TargetAssignDistributionSetEvent) event).getActions()).isNotEmpty();
assertThat(((TargetAssignDistributionSetEvent) event).getControllerId()).isNotEmpty();
assertThat(((TargetAssignDistributionSetEvent) event).getDistributionSetId()).isNotNull(); assertThat(((TargetAssignDistributionSetEvent) event).getDistributionSetId()).isNotNull();
} }

View File

@@ -26,11 +26,6 @@
<artifactId>hawkbit-repository-api</artifactId> <artifactId>hawkbit-repository-api</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-dmf-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.security</groupId> <groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId> <artifactId>spring-security-web</artifactId>

View File

@@ -8,7 +8,6 @@
*/ */
package org.eclipse.hawkbit.security; package org.eclipse.hawkbit.security;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger; import org.slf4j.Logger;

View File

@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.security;
import java.util.Optional; import java.util.Optional;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
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.model.Target; import org.eclipse.hawkbit.repository.model.Target;

View File

@@ -11,7 +11,6 @@ package org.eclipse.hawkbit.security;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;

View File

@@ -8,8 +8,6 @@
*/ */
package org.eclipse.hawkbit.security; package org.eclipse.hawkbit.security;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
/** /**
* An anonymous controller filter which is only enabled in case of anonymous * An anonymous controller filter which is only enabled in case of anonymous
* access is granted. This should only be for development purposes. * access is granted. This should only be for development purposes.

View File

@@ -8,7 +8,6 @@
*/ */
package org.eclipse.hawkbit.security; package org.eclipse.hawkbit.security;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;

View File

@@ -12,7 +12,6 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;

View File

@@ -6,7 +6,7 @@
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
*/ */
package org.eclipse.hawkbit.dmf.json.model; package org.eclipse.hawkbit.security;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;

View File

@@ -11,7 +11,6 @@ package org.eclipse.hawkbit.security;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;

View File

@@ -15,10 +15,9 @@ import static org.mockito.Mockito.when;
import java.util.Collection; import java.util.Collection;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken;
import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;

View File

@@ -276,7 +276,7 @@ public class DistributionsView extends AbstractNotificationView implements Brows
@Override @Override
protected Map<Class<?>, RefreshableContainer> getSupportedPushEvents() { protected Map<Class<?>, RefreshableContainer> getSupportedPushEvents() {
final Map<Class<?>, RefreshableContainer> supportedEvents = Maps.newHashMapWithExpectedSize(2); final Map<Class<?>, RefreshableContainer> supportedEvents = Maps.newHashMapWithExpectedSize(4);
supportedEvents.put(DistributionSetCreatedEventContainer.class, distributionTableLayout.getTable()); supportedEvents.put(DistributionSetCreatedEventContainer.class, distributionTableLayout.getTable());
supportedEvents.put(DistributionSetDeletedEventContainer.class, distributionTableLayout.getTable()); supportedEvents.put(DistributionSetDeletedEventContainer.class, distributionTableLayout.getTable());

View File

@@ -164,7 +164,7 @@
<json.version>20141113</json.version> <json.version>20141113</json.version>
<rsql-parser.version>2.1.0</rsql-parser.version> <rsql-parser.version>2.1.0</rsql-parser.version>
<jayway.awaitility.version>1.7.0</jayway.awaitility.version> <jayway.awaitility.version>1.7.0</jayway.awaitility.version>
<io-protostuff.version>1.5.3</io-protostuff.version> <io-protostuff.version>1.5.6</io-protostuff.version>
<!-- Misc libraries versions - END --> <!-- Misc libraries versions - END -->
<!-- Release - START --> <!-- Release - START -->