Feature add optional name to thing created (#888)
* First implementation pushed because of debugging purpose Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Add name field and tests regarding name field functionality in THING_CREATED Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * SonarQube realted changes in name field functionality in THING_CREATED Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Add name field and tests regarding name field functionality in UPDATE_ATTRIBUTES Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Adapt documentation due to name field in THING_CREATED and UPDATE_ATTRIBUTES Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Add integration tests regarding name field functionality in THING_CREATED Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Reformat after finding format bug regarding THING_CREATED Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Reformat after finding the real format bug regarding THING_CREATED Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Reformat regarding THING_CREATED Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Use constant in THING_CREATED Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Format in THING_CREATED Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Resolving peer review comments regarding THING_CREATED Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Resolving peer review comments (organize imports) regarding THING_CREATED Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Refactoring regarding THING_CREATED Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Refactoring due to peer review Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Refactoring due to peer review Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Excluding UPDATE_ATTRIBUTES changes and provide functionality of updating the name property in THING_CREATED message Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Refactoring due to peer review Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Refactoring due to peer review Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Fix SonarQube finding Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Merge master into current branch Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com> * Fix peer review findings Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>
This commit is contained in:
committed by
Dominic Schabel
parent
b50a82fc0f
commit
af0f7ceb5a
@@ -52,12 +52,22 @@ Message Properties | Description
|
|||||||
content_type | The content type of the payload | String | true
|
content_type | The content type of the payload | String | true
|
||||||
reply_to | Exchange to reply to. The default is sp.direct.exchange which is bound to the sp_direct_queue | String | false
|
reply_to | Exchange to reply to. The default is sp.direct.exchange which is bound to the sp_direct_queue | String | false
|
||||||
|
|
||||||
Example headers
|
Example headers and payload:
|
||||||
|
|
||||||
Header | MessageProperties
|
Header | MessageProperties
|
||||||
----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------
|
||||||
type=THING\_CREATED <br /> tenant=tenant123 <br /> thingId=abc <br /> sender=Lwm2m | content\_type=application/json <br /> reply_to (optional) =sp.connector.replyTo
|
type=THING\_CREATED <br /> tenant=tenant123 <br /> thingId=abc <br /> sender=Lwm2m | content\_type=application/json <br /> reply_to (optional) =sp.connector.replyTo
|
||||||
|
|
||||||
|
Payload Template (optional):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "String"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The "name" property specifies the name of the thing, which by default is the thing ID. This property is optional.
|
||||||
|
|
||||||
|
|
||||||
### THING_REMOVED
|
### THING_REMOVED
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.amqp;
|
|||||||
|
|
||||||
import static org.eclipse.hawkbit.repository.RepositoryConstants.MAX_ACTION_COUNT;
|
import static org.eclipse.hawkbit.repository.RepositoryConstants.MAX_ACTION_COUNT;
|
||||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED;
|
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED;
|
||||||
|
import static org.springframework.util.StringUtils.hasText;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@@ -26,6 +27,7 @@ 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.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.DmfCreateThing;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.DmfUpdateMode;
|
import org.eclipse.hawkbit.dmf.json.model.DmfUpdateMode;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||||
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
||||||
@@ -51,6 +53,7 @@ import org.springframework.amqp.AmqpRejectAndDontRequeueException;
|
|||||||
import org.springframework.amqp.core.Message;
|
import org.springframework.amqp.core.Message;
|
||||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.amqp.support.converter.MessageConversionException;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.messaging.handler.annotation.Header;
|
import org.springframework.messaging.handler.annotation.Header;
|
||||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||||
@@ -84,6 +87,8 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
|
|
||||||
private static final String THING_ID_NULL = "ThingId is null";
|
private static final String THING_ID_NULL = "ThingId is null";
|
||||||
|
|
||||||
|
private static final String EMPTY_MESSAGE_BODY = "\"\"";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@@ -122,7 +127,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
* the message type
|
* the message type
|
||||||
* @param tenant
|
* @param tenant
|
||||||
* the contentType of the message
|
* the contentType of the message
|
||||||
*
|
|
||||||
* @return a message if <null> no message is send back to sender
|
* @return a message if <null> no message is send back to sender
|
||||||
*/
|
*/
|
||||||
@RabbitListener(queues = "${hawkbit.dmf.rabbitmq.receiverQueue:dmf_receiver}", containerFactory = "listenerContainerFactory")
|
@RabbitListener(queues = "${hawkbit.dmf.rabbitmq.receiverQueue:dmf_receiver}", containerFactory = "listenerContainerFactory")
|
||||||
@@ -198,12 +202,14 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to create a new target or to find the target if it already exists.
|
* Method to create a new target or to find the target if it already exists and
|
||||||
|
* update its poll time, status and optionally its name.
|
||||||
*
|
*
|
||||||
* @param targetID
|
* @param message
|
||||||
* the ID of the target/thing
|
* the message that contains replyTo property and optionally the name
|
||||||
* @param ip
|
* in body
|
||||||
* the ip of the target/thing
|
* @param virtualHost
|
||||||
|
* the virtual host
|
||||||
*/
|
*/
|
||||||
private void registerTarget(final Message message, final String virtualHost) {
|
private void registerTarget(final Message message, final String virtualHost) {
|
||||||
final String thingId = getStringHeaderKey(message, MessageHeaderKey.THING_ID, THING_ID_NULL);
|
final String thingId = getStringHeaderKey(message, MessageHeaderKey.THING_ID, THING_ID_NULL);
|
||||||
@@ -215,14 +221,29 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final URI amqpUri = IpUtil.createAmqpUri(virtualHost, replyTo);
|
final URI amqpUri = IpUtil.createAmqpUri(virtualHost, replyTo);
|
||||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist(thingId, amqpUri);
|
final Target target;
|
||||||
|
if (isOptionalMessageBodyEmpty(message)) {
|
||||||
|
target = controllerManagement.findOrRegisterTargetIfItDoesNotExist(thingId, amqpUri);
|
||||||
|
} else {
|
||||||
|
checkContentTypeJson(message);
|
||||||
|
|
||||||
|
target = controllerManagement.findOrRegisterTargetIfItDoesNotExist(thingId, amqpUri, convertMessage(message, DmfCreateThing.class).getName());
|
||||||
|
|
||||||
|
}
|
||||||
LOG.debug("Target {} reported online state.", thingId);
|
LOG.debug("Target {} reported online state.", thingId);
|
||||||
sendUpdateCommandToTarget(target);
|
sendUpdateCommandToTarget(target);
|
||||||
} catch (EntityAlreadyExistsException e) {
|
} catch (final EntityAlreadyExistsException e) {
|
||||||
throw new AmqpRejectAndDontRequeueException("Target already registered, message will be ignored!", e);
|
throw new AmqpRejectAndDontRequeueException(
|
||||||
|
"Tried to register previously registered target, message will be ignored!", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isOptionalMessageBodyEmpty(final Message message) {
|
||||||
|
// empty byte array message body is serialized to double-quoted string
|
||||||
|
// by message converter and should also be considered as empty
|
||||||
|
return isMessageBodyEmpty(message) || EMPTY_MESSAGE_BODY.equals(new String(message.getBody()));
|
||||||
|
}
|
||||||
|
|
||||||
private void sendUpdateCommandToTarget(final Target target) {
|
private void sendUpdateCommandToTarget(final Target target) {
|
||||||
if (isMultiAssignmentsEnabled()) {
|
if (isMultiAssignmentsEnabled()) {
|
||||||
sendCurrentActionsAsMultiActionToTarget(target);
|
sendCurrentActionsAsMultiActionToTarget(target);
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public class BaseAmqpService {
|
|||||||
return rabbitTemplate.getMessageConverter();
|
return rabbitTemplate.getMessageConverter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isMessageBodyEmpty(final Message message) {
|
protected static boolean isMessageBodyEmpty(final Message message) {
|
||||||
return message.getBody() == null || message.getBody().length == 0;
|
return message.getBody() == null || message.getBody().length == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
|
|||||||
import org.eclipse.hawkbit.dmf.json.model.DmfActionStatus;
|
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.DmfCreateThing;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse;
|
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.DmfUpdateMode;
|
import org.eclipse.hawkbit.dmf.json.model.DmfUpdateMode;
|
||||||
import org.eclipse.hawkbit.repository.ArtifactManagement;
|
import org.eclipse.hawkbit.repository.ArtifactManagement;
|
||||||
@@ -70,6 +71,7 @@ import org.springframework.amqp.core.Message;
|
|||||||
import org.springframework.amqp.core.MessageProperties;
|
import org.springframework.amqp.core.MessageProperties;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
|
import org.springframework.amqp.support.converter.MessageConversionException;
|
||||||
import org.springframework.amqp.support.converter.MessageConverter;
|
import org.springframework.amqp.support.converter.MessageConverter;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
@@ -82,8 +84,8 @@ import io.qameta.allure.Story;
|
|||||||
@Story("AmqpMessage Handler Service Test")
|
@Story("AmqpMessage Handler Service Test")
|
||||||
public class AmqpMessageHandlerServiceTest {
|
public class AmqpMessageHandlerServiceTest {
|
||||||
|
|
||||||
private static final String FAIL_MESSAGE_AMQP_REJECT_REASON = AmqpRejectAndDontRequeueException.class.getSimpleName()
|
private static final String FAIL_MESSAGE_AMQP_REJECT_REASON = AmqpRejectAndDontRequeueException.class
|
||||||
+ " was expected, ";
|
.getSimpleName() + " was expected, ";
|
||||||
|
|
||||||
private static final String SHA1 = "12345";
|
private static final String SHA1 = "12345";
|
||||||
private static final String VIRTUAL_HOST = "vHost";
|
private static final String VIRTUAL_HOST = "vHost";
|
||||||
@@ -136,6 +138,9 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<String> targetIdCaptor;
|
private ArgumentCaptor<String> targetIdCaptor;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<URI> uriCaptor;
|
||||||
|
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<UpdateMode> modeCaptor;
|
private ArgumentCaptor<UpdateMode> modeCaptor;
|
||||||
|
|
||||||
@@ -176,23 +181,60 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
@Description("Tests the creation of a target/thing by calling the same method that incoming RabbitMQ messages would access.")
|
@Description("Tests the creation of a target/thing by calling the same method that incoming RabbitMQ messages would access.")
|
||||||
public void createThing() {
|
public void createThing() {
|
||||||
final String knownThingId = "1";
|
final String knownThingId = "1";
|
||||||
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED);
|
|
||||||
messageProperties.setHeader(MessageHeaderKey.THING_ID, "1");
|
|
||||||
final Message message = messageConverter.toMessage(new byte[0], messageProperties);
|
|
||||||
|
|
||||||
final Target targetMock = mock(Target.class);
|
final Target targetMock = mock(Target.class);
|
||||||
|
|
||||||
final ArgumentCaptor<String> targetIdCaptor = ArgumentCaptor.forClass(String.class);
|
targetIdCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
final ArgumentCaptor<URI> uriCaptor = ArgumentCaptor.forClass(URI.class);
|
uriCaptor = ArgumentCaptor.forClass(URI.class);
|
||||||
when(controllerManagementMock.findOrRegisterTargetIfItDoesNotExist(targetIdCaptor.capture(),
|
when(controllerManagementMock.findOrRegisterTargetIfItDoesNotExist(targetIdCaptor.capture(),
|
||||||
uriCaptor.capture())).thenReturn(targetMock);
|
uriCaptor.capture())).thenReturn(targetMock);
|
||||||
when(controllerManagementMock.findOldestActiveActionByTarget(any())).thenReturn(Optional.empty());
|
when(controllerManagementMock.findOldestActiveActionByTarget(any())).thenReturn(Optional.empty());
|
||||||
|
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, VIRTUAL_HOST);
|
amqpMessageHandlerService.onMessage(createMessage(new byte[0], getThingCreatedMessageProperties(knownThingId)),
|
||||||
|
MessageType.THING_CREATED.name(), TENANT, VIRTUAL_HOST);
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertThat(targetIdCaptor.getValue()).as("Thing id is wrong").isEqualTo(knownThingId);
|
assertThat(targetIdCaptor.getValue()).as("Thing id is wrong").isEqualTo(knownThingId);
|
||||||
assertThat(uriCaptor.getValue().toString()).as("Uri is not right").isEqualTo("amqp://"+VIRTUAL_HOST+"/MyTest");
|
assertThat(uriCaptor.getValue().toString()).as("Uri is not right")
|
||||||
|
.isEqualTo("amqp://" + VIRTUAL_HOST + "/MyTest");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Tests the creation of a target/thing with specified name by calling the same method that incoming RabbitMQ messages would access.")
|
||||||
|
public void createThingWithName() {
|
||||||
|
final String knownThingId = "2";
|
||||||
|
final DmfCreateThing targetProperties = new DmfCreateThing();
|
||||||
|
targetProperties.setName("NonDefaultTargetName");
|
||||||
|
|
||||||
|
final Target targetMock = mock(Target.class);
|
||||||
|
|
||||||
|
targetIdCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
|
uriCaptor = ArgumentCaptor.forClass(URI.class);
|
||||||
|
final ArgumentCaptor<String> targetNameCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
|
|
||||||
|
when(controllerManagementMock.findOrRegisterTargetIfItDoesNotExist(targetIdCaptor.capture(),
|
||||||
|
uriCaptor.capture(), targetNameCaptor.capture())).thenReturn(targetMock);
|
||||||
|
when(controllerManagementMock.findOldestActiveActionByTarget(any())).thenReturn(Optional.empty());
|
||||||
|
|
||||||
|
amqpMessageHandlerService.onMessage(
|
||||||
|
createMessage(targetProperties, getThingCreatedMessageProperties(knownThingId)),
|
||||||
|
MessageType.THING_CREATED.name(), TENANT, "vHost");
|
||||||
|
|
||||||
|
assertThat(targetIdCaptor.getValue()).as("Thing id is wrong").isEqualTo(knownThingId);
|
||||||
|
assertThat(uriCaptor.getValue().toString()).as("Uri is not right").isEqualTo("amqp://vHost/MyTest");
|
||||||
|
assertThat(targetNameCaptor.getValue()).as("Thing name is not right").isEqualTo(targetProperties.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Tests not allowed body in message")
|
||||||
|
public void createThingWithWrongBody() {
|
||||||
|
final String knownThingId = "3";
|
||||||
|
|
||||||
|
assertThatExceptionOfType(MessageConversionException.class)
|
||||||
|
.as("MessageConversionException was excepeted due to wrong body")
|
||||||
|
.isThrownBy(() -> amqpMessageHandlerService.onMessage(
|
||||||
|
createMessage("Not allowed Body".getBytes(), getThingCreatedMessageProperties(knownThingId)),
|
||||||
|
MessageType.THING_CREATED.name(), TENANT, VIRTUAL_HOST));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -308,15 +350,13 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
final Message message = new Message(new byte[0], messageProperties);
|
final Message message = new Message(new byte[0], messageProperties);
|
||||||
|
|
||||||
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
|
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
|
||||||
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to unknown message type")
|
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to unknown message type").isThrownBy(
|
||||||
.isThrownBy(() -> amqpMessageHandlerService.onMessage(message, "unknownMessageType", TENANT,
|
() -> amqpMessageHandlerService.onMessage(message, "unknownMessageType", TENANT, VIRTUAL_HOST));
|
||||||
VIRTUAL_HOST));
|
|
||||||
|
|
||||||
messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic");
|
messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic");
|
||||||
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
|
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
|
||||||
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to unknown topic")
|
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to unknown topic").isThrownBy(() -> amqpMessageHandlerService
|
||||||
.isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT,
|
.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST));
|
||||||
VIRTUAL_HOST));
|
|
||||||
|
|
||||||
messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name());
|
messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name());
|
||||||
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
|
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
|
||||||
@@ -532,12 +572,12 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
final String knownThingId = "1";
|
final String knownThingId = "1";
|
||||||
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_REMOVED);
|
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_REMOVED);
|
||||||
messageProperties.setHeader(MessageHeaderKey.THING_ID, knownThingId);
|
messageProperties.setHeader(MessageHeaderKey.THING_ID, knownThingId);
|
||||||
final Message message = messageConverter.toMessage(new byte[0],messageProperties);
|
final Message message = messageConverter.toMessage(new byte[0], messageProperties);
|
||||||
|
|
||||||
// test
|
// test
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.THING_REMOVED.name(), TENANT, VIRTUAL_HOST);
|
amqpMessageHandlerService.onMessage(message, MessageType.THING_REMOVED.name(), TENANT, VIRTUAL_HOST);
|
||||||
|
|
||||||
//verify
|
// verify
|
||||||
verify(controllerManagementMock).deleteExistingTarget(knownThingId);
|
verify(controllerManagementMock).deleteExistingTarget(knownThingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,4 +594,13 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
VIRTUAL_HOST));
|
VIRTUAL_HOST));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MessageProperties getThingCreatedMessageProperties(String thingId) {
|
||||||
|
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED);
|
||||||
|
messageProperties.setHeader(MessageHeaderKey.THING_ID, thingId);
|
||||||
|
return messageProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Message createMessage(Object object, MessageProperties messageProperties) {
|
||||||
|
return messageConverter.toMessage(object, messageProperties);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2019 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.dmf.json.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON representation of the Attribute THING_CREATED message.
|
||||||
|
*/
|
||||||
|
@JsonInclude(Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class DmfCreateThing {
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -46,8 +46,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
|||||||
public interface ControllerManagement {
|
public interface ControllerManagement {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an {@link ActionStatus} for a cancel {@link Action} including
|
* Adds an {@link ActionStatus} for a cancel {@link Action} including potential
|
||||||
* potential state changes for the target and the {@link Action} itself.
|
* state changes for the target and the {@link Action} itself.
|
||||||
*
|
*
|
||||||
* @param create
|
* @param create
|
||||||
* to be added
|
* to be added
|
||||||
@@ -57,8 +57,8 @@ public interface ControllerManagement {
|
|||||||
* if a given entity already exists
|
* if a given entity already exists
|
||||||
*
|
*
|
||||||
* @throws QuotaExceededException
|
* @throws QuotaExceededException
|
||||||
* if more than the allowed number of status entries or messages
|
* if more than the allowed number of status entries or messages per
|
||||||
* per entry are inserted
|
* entry are inserted
|
||||||
* @throws EntityNotFoundException
|
* @throws EntityNotFoundException
|
||||||
* if given action does not exist
|
* if given action does not exist
|
||||||
* @throws ConstraintViolationException
|
* @throws ConstraintViolationException
|
||||||
@@ -93,8 +93,8 @@ public interface ControllerManagement {
|
|||||||
@NotNull Collection<Long> moduleId);
|
@NotNull Collection<Long> moduleId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple addition of a new {@link ActionStatus} entry to the {@link Action}
|
* Simple addition of a new {@link ActionStatus} entry to the {@link Action} .
|
||||||
* . No state changes.
|
* No state changes.
|
||||||
*
|
*
|
||||||
* @param create
|
* @param create
|
||||||
* to add to the action
|
* to add to the action
|
||||||
@@ -102,8 +102,8 @@ public interface ControllerManagement {
|
|||||||
* @return created {@link ActionStatus} entity
|
* @return created {@link ActionStatus} entity
|
||||||
*
|
*
|
||||||
* @throws QuotaExceededException
|
* @throws QuotaExceededException
|
||||||
* if more than the allowed number of status entries or messages
|
* if more than the allowed number of status entries or messages per
|
||||||
* per entry are inserted
|
* entry are inserted
|
||||||
* @throws EntityNotFoundException
|
* @throws EntityNotFoundException
|
||||||
* if given action does not exist
|
* if given action does not exist
|
||||||
* @throws ConstraintViolationException
|
* @throws ConstraintViolationException
|
||||||
@@ -124,8 +124,8 @@ public interface ControllerManagement {
|
|||||||
* @throws EntityAlreadyExistsException
|
* @throws EntityAlreadyExistsException
|
||||||
* if a given entity already exists
|
* if a given entity already exists
|
||||||
* @throws QuotaExceededException
|
* @throws QuotaExceededException
|
||||||
* if more than the allowed number of status entries or messages
|
* if more than the allowed number of status entries or messages per
|
||||||
* per entry are inserted
|
* entry are inserted
|
||||||
* @throws EntityNotFoundException
|
* @throws EntityNotFoundException
|
||||||
* if action status not exist
|
* if action status not exist
|
||||||
* @throws ConstraintViolationException
|
* @throws ConstraintViolationException
|
||||||
@@ -140,7 +140,7 @@ public interface ControllerManagement {
|
|||||||
* {@link Target}.
|
* {@link Target}.
|
||||||
*
|
*
|
||||||
* For performance reasons this method does not throw
|
* For performance reasons this method does not throw
|
||||||
* {@link EntityNotFoundException} in case target with given controllerId
|
* {@link EntityNotFoundException} in case target with given controlelrId
|
||||||
* does not exist but will return an {@link Optional#empty()} instead.
|
* does not exist but will return an {@link Optional#empty()} instead.
|
||||||
*
|
*
|
||||||
* @param controllerId
|
* @param controllerId
|
||||||
@@ -152,8 +152,8 @@ public interface ControllerManagement {
|
|||||||
Optional<Action> findOldestActiveActionByTarget(@NotEmpty String controllerId);
|
Optional<Action> findOldestActiveActionByTarget(@NotEmpty String controllerId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all active actions which are assigned to the target with the
|
* Retrieves all active actions which are assigned to the target with the given
|
||||||
* given controller ID.
|
* controller ID.
|
||||||
*
|
*
|
||||||
* @param pageable
|
* @param pageable
|
||||||
* pagination parameter
|
* pagination parameter
|
||||||
@@ -165,8 +165,7 @@ public interface ControllerManagement {
|
|||||||
Page<Action> findActiveActionsByTarget(@NotNull Pageable pageable, @NotEmpty String controllerId);
|
Page<Action> findActiveActionsByTarget(@NotNull Pageable pageable, @NotEmpty String controllerId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@link Action} entity for given actionId with all lazy
|
* Get the {@link Action} entity for given actionId with all lazy attributes.
|
||||||
* attributes.
|
|
||||||
*
|
*
|
||||||
* @param actionId
|
* @param actionId
|
||||||
* to be id of the action
|
* to be id of the action
|
||||||
@@ -176,8 +175,7 @@ public interface ControllerManagement {
|
|||||||
Optional<Action> findActionWithDetails(long actionId);
|
Optional<Action> findActionWithDetails(long actionId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all the {@link ActionStatus} entries of the given
|
* Retrieves all the {@link ActionStatus} entries of the given {@link Action}.
|
||||||
* {@link Action}.
|
|
||||||
*
|
*
|
||||||
* @param pageReq
|
* @param pageReq
|
||||||
* pagination parameter
|
* pagination parameter
|
||||||
@@ -192,11 +190,10 @@ public interface ControllerManagement {
|
|||||||
Page<ActionStatus> findActionStatusByAction(@NotNull Pageable pageReq, long actionId);
|
Page<ActionStatus> findActionStatusByAction(@NotNull Pageable pageReq, long actionId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register new target in the repository (plug-and-play) and in case it
|
* Register new target in the repository (plug-and-play) and in case it already
|
||||||
* already exists updates {@link Target#getAddress()} and
|
* exists updates {@link Target#getAddress()} and
|
||||||
* {@link Target#getLastTargetQuery()} and switches if
|
* {@link Target#getLastTargetQuery()} and switches if
|
||||||
* {@link TargetUpdateStatus#UNKNOWN} to
|
* {@link TargetUpdateStatus#UNKNOWN} to {@link TargetUpdateStatus#REGISTERED}.
|
||||||
* {@link TargetUpdateStatus#REGISTERED}.
|
|
||||||
*
|
*
|
||||||
* @param controllerId
|
* @param controllerId
|
||||||
* reference
|
* reference
|
||||||
@@ -208,14 +205,31 @@ public interface ControllerManagement {
|
|||||||
Target findOrRegisterTargetIfItDoesNotExist(@NotEmpty String controllerId, @NotNull URI address);
|
Target findOrRegisterTargetIfItDoesNotExist(@NotEmpty String controllerId, @NotNull URI address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves last {@link Action} for a download of an artifact of given
|
* Register new target in the repository (plug-and-play) and in case it already
|
||||||
* module and target if exists and is not canceled.
|
* exists updates {@link Target#getAddress()} and
|
||||||
|
* {@link Target#getLastTargetQuery()} and {@link Target#getName()} and switches if
|
||||||
|
* {@link TargetUpdateStatus#UNKNOWN} to {@link TargetUpdateStatus#REGISTERED}.
|
||||||
|
*
|
||||||
|
* @param controllerId
|
||||||
|
* reference
|
||||||
|
* @param address
|
||||||
|
* the client IP address of the target, might be {@code null}
|
||||||
|
* @param name
|
||||||
|
* the name of the target
|
||||||
|
* @return target reference
|
||||||
|
*/
|
||||||
|
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
|
||||||
|
Target findOrRegisterTargetIfItDoesNotExist(@NotEmpty String controllerId, @NotNull URI address, String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves last {@link Action} for a download of an artifact of given module
|
||||||
|
* and target if exists and is not canceled.
|
||||||
*
|
*
|
||||||
* @param controllerId
|
* @param controllerId
|
||||||
* to look for
|
* to look for
|
||||||
* @param moduleId
|
* @param moduleId
|
||||||
* of the the {@link SoftwareModule} that should be assigned to
|
* of the the {@link SoftwareModule} that should be assigned to the
|
||||||
* the target
|
* target
|
||||||
* @return last {@link Action} for given combination
|
* @return last {@link Action} for given combination
|
||||||
*
|
*
|
||||||
* @throws EntityNotFoundException
|
* @throws EntityNotFoundException
|
||||||
@@ -253,18 +267,18 @@ public interface ControllerManagement {
|
|||||||
int getMaintenanceWindowPollCount();
|
int getMaintenanceWindowPollCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns polling time based on the maintenance window for an action.
|
* Returns polling time based on the maintenance window for an action. Server
|
||||||
* Server will reduce the polling interval as the start time for maintenance
|
* will reduce the polling interval as the start time for maintenance window
|
||||||
* window approaches, so that at least these many attempts are made between
|
* approaches, so that at least these many attempts are made between current
|
||||||
* current polling until start of maintenance window. Poll time keeps
|
* polling until start of maintenance window. Poll time keeps reducing with
|
||||||
* reducing with MinPollingTime as lower limit
|
* MinPollingTime as lower limit
|
||||||
* {@link TenantConfigurationKey#MIN_POLLING_TIME_INTERVAL}. After the start
|
* {@link TenantConfigurationKey#MIN_POLLING_TIME_INTERVAL}. After the start of
|
||||||
* of maintenance window, it resets to default
|
* maintenance window, it resets to default
|
||||||
* {@link TenantConfigurationKey#POLLING_TIME_INTERVAL}.
|
* {@link TenantConfigurationKey#POLLING_TIME_INTERVAL}.
|
||||||
*
|
*
|
||||||
* @param actionId
|
* @param actionId
|
||||||
* id the {@link Action} for which polling time is calculated
|
* id the {@link Action} for which polling time is calculated based
|
||||||
* based on it having maintenance window or not
|
* on it having maintenance window or not
|
||||||
*
|
*
|
||||||
* @return current {@link TenantConfigurationKey#POLLING_TIME_INTERVAL}.
|
* @return current {@link TenantConfigurationKey#POLLING_TIME_INTERVAL}.
|
||||||
*/
|
*/
|
||||||
@@ -272,20 +286,20 @@ public interface ControllerManagement {
|
|||||||
String getPollingTimeForAction(long actionId);
|
String getPollingTimeForAction(long actionId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a given target has currently or has even been assigned to the
|
* Checks if a given target has currently or has even been assigned to the given
|
||||||
* given artifact through the action history list. This can e.g. indicate if
|
* artifact through the action history list. This can e.g. indicate if a target
|
||||||
* a target is allowed to download a given artifact because it has currently
|
* is allowed to download a given artifact because it has currently assigned or
|
||||||
* assigned or had ever been assigned to the target and so it's visible to a
|
* had ever been assigned to the target and so it's visible to a specific target
|
||||||
* specific target e.g. for downloading.
|
* e.g. for downloading.
|
||||||
*
|
*
|
||||||
* @param controllerId
|
* @param controllerId
|
||||||
* the ID of the target to check
|
* the ID of the target to check
|
||||||
* @param sha1Hash
|
* @param sha1Hash
|
||||||
* of the artifact to verify if the given target had even been
|
* of the artifact to verify if the given target had even been
|
||||||
* assigned to
|
* assigned to
|
||||||
* @return {@code true} if the given target has currently or had ever a
|
* @return {@code true} if the given target has currently or had ever a relation
|
||||||
* relation to the given artifact through the action history,
|
* to the given artifact through the action history, otherwise
|
||||||
* otherwise {@code false}
|
* {@code false}
|
||||||
*
|
*
|
||||||
* @throws EntityNotFoundException
|
* @throws EntityNotFoundException
|
||||||
* if target with given ID does not exist
|
* if target with given ID does not exist
|
||||||
@@ -294,20 +308,20 @@ public interface ControllerManagement {
|
|||||||
boolean hasTargetArtifactAssigned(@NotEmpty String controllerId, @NotEmpty String sha1Hash);
|
boolean hasTargetArtifactAssigned(@NotEmpty String controllerId, @NotEmpty String sha1Hash);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a given target has currently or has even been assigned to the
|
* Checks if a given target has currently or has even been assigned to the given
|
||||||
* given artifact through the action history list. This can e.g. indicate if
|
* artifact through the action history list. This can e.g. indicate if a target
|
||||||
* a target is allowed to download a given artifact because it has currently
|
* is allowed to download a given artifact because it has currently assigned or
|
||||||
* assigned or had ever been assigned to the target and so it's visible to a
|
* had ever been assigned to the target and so it's visible to a specific target
|
||||||
* specific target e.g. for downloading.
|
* e.g. for downloading.
|
||||||
*
|
*
|
||||||
* @param targetId
|
* @param targetId
|
||||||
* the ID of the target to check
|
* the ID of the target to check
|
||||||
* @param sha1Hash
|
* @param sha1Hash
|
||||||
* of the artifact to verify if the given target had even been
|
* of the artifact to verify if the given target had even been
|
||||||
* assigned to
|
* assigned to
|
||||||
* @return {@code true} if the given target has currently or had ever a
|
* @return {@code true} if the given target has currently or had ever a relation
|
||||||
* relation to the given artifact through the action history,
|
* to the given artifact through the action history, otherwise
|
||||||
* otherwise {@code false}
|
* {@code false}
|
||||||
*
|
*
|
||||||
* @throws EntityNotFoundException
|
* @throws EntityNotFoundException
|
||||||
* if target with given ID does not exist
|
* if target with given ID does not exist
|
||||||
@@ -316,8 +330,8 @@ public interface ControllerManagement {
|
|||||||
boolean hasTargetArtifactAssigned(long targetId, @NotEmpty String sha1Hash);
|
boolean hasTargetArtifactAssigned(long targetId, @NotEmpty String sha1Hash);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers retrieved status for given {@link Target} and {@link Action} if
|
* Registers retrieved status for given {@link Target} and {@link Action} if it
|
||||||
* it does not exist yet.
|
* does not exist yet.
|
||||||
*
|
*
|
||||||
* @param actionId
|
* @param actionId
|
||||||
* to the handle status for
|
* to the handle status for
|
||||||
@@ -371,9 +385,8 @@ public interface ControllerManagement {
|
|||||||
Optional<Target> getByControllerId(@NotEmpty String controllerId);
|
Optional<Target> getByControllerId(@NotEmpty String controllerId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds {@link Target} based on given ID returns found Target without
|
* Finds {@link Target} based on given ID returns found Target without details,
|
||||||
* details, i.e. NO {@link Target#getTags()} and {@link Target#getActions()}
|
* i.e. NO {@link Target#getTags()} and {@link Target#getActions()} possible.
|
||||||
* possible.
|
|
||||||
*
|
*
|
||||||
* @param targetId
|
* @param targetId
|
||||||
* to look for.
|
* to look for.
|
||||||
@@ -385,21 +398,20 @@ public interface ControllerManagement {
|
|||||||
Optional<Target> get(long targetId);
|
Optional<Target> get(long targetId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the specified number of messages from action history of the
|
* Retrieves the specified number of messages from action history of the given
|
||||||
* given {@link Action} based on messageCount. Regardless of the value of
|
* {@link Action} based on messageCount. Regardless of the value of
|
||||||
* messageCount, in order to restrict resource utilisation by controllers,
|
* messageCount, in order to restrict resource utilisation by controllers,
|
||||||
* maximum number of messages that are retrieved from database is limited by
|
* maximum number of messages that are retrieved from database is limited by
|
||||||
* {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}. messageCount
|
* {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}. messageCount less
|
||||||
* less then zero, retrieves the maximum allowed number of action status
|
* then zero, retrieves the maximum allowed number of action status messages
|
||||||
* messages from history; messageCount equal zero, does not retrieve any
|
* from history; messageCount equal zero, does not retrieve any message; and
|
||||||
* message; and messageCount larger then zero, retrieves the specified
|
* messageCount larger then zero, retrieves the specified number of messages,
|
||||||
* number of messages, limited by maximum allowed number. A controller sends
|
* limited by maximum allowed number. A controller sends the feedback for an
|
||||||
* the feedback for an {@link ActionStatus} as a list of messages; while
|
* {@link ActionStatus} as a list of messages; while returning the messages,
|
||||||
* returning the messages, even though the messages from multiple
|
* even though the messages from multiple {@link ActionStatus} are retrieved in
|
||||||
* {@link ActionStatus} are retrieved in descending order by the reported
|
* descending order by the reported time ({@link ActionStatus#getOccurredAt()}),
|
||||||
* time ({@link ActionStatus#getOccurredAt()}), i.e. latest ActionStatus
|
* i.e. latest ActionStatus first, the sub-ordering of messages from within
|
||||||
* first, the sub-ordering of messages from within single
|
* single {@link ActionStatus} is unspecified.
|
||||||
* {@link ActionStatus} is unspecified.
|
|
||||||
*
|
*
|
||||||
* @param actionId
|
* @param actionId
|
||||||
* to be filtered on
|
* to be filtered on
|
||||||
@@ -412,10 +424,10 @@ public interface ControllerManagement {
|
|||||||
List<String> getActionHistoryMessages(long actionId, int messageCount);
|
List<String> getActionHistoryMessages(long actionId, int messageCount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels given {@link Action} for this {@link Target}. However, it might
|
* Cancels given {@link Action} for this {@link Target}. However, it might be
|
||||||
* be possible that the controller will continue to work on the
|
* possible that the controller will continue to work on the cancellation. The
|
||||||
* cancellation. The controller needs to acknowledge or reject the
|
* controller needs to acknowledge or reject the cancellation using
|
||||||
* cancellation using {@link DdiRootController#postCancelActionFeedback}.
|
* {@link DdiRootController#postCancelActionFeedback}.
|
||||||
*
|
*
|
||||||
* @param actionId
|
* @param actionId
|
||||||
* to be canceled
|
* to be canceled
|
||||||
@@ -442,8 +454,7 @@ public interface ControllerManagement {
|
|||||||
void updateActionExternalRef(long actionId, @NotEmpty String externalRef);
|
void updateActionExternalRef(long actionId, @NotEmpty String externalRef);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves list of {@link Action}s which matches the provided
|
* Retrieves list of {@link Action}s which matches the provided externalRefs.
|
||||||
* externalRefs.
|
|
||||||
*
|
*
|
||||||
* @param externalRefs
|
* @param externalRefs
|
||||||
* for which the actions need to be fetched.
|
* for which the actions need to be fetched.
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ import org.springframework.transaction.PlatformTransactionManager;
|
|||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.transaction.support.TransactionCallback;
|
import org.springframework.transaction.support.TransactionCallback;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
@@ -238,11 +239,11 @@ public class JpaControllerManagement implements ControllerManagement {
|
|||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param defaultEventInterval
|
* @param defaultEventInterval
|
||||||
* default timer value to use for interval between events.
|
* default timer value to use for interval between events. This puts
|
||||||
* This puts an upper bound for the timer value
|
* an upper bound for the timer value
|
||||||
* @param minimumEventInterval
|
* @param minimumEventInterval
|
||||||
* for loading {@link DistributionSet#getModules()}. This
|
* for loading {@link DistributionSet#getModules()}. This puts a
|
||||||
* puts a lower bound to the timer value
|
* lower bound to the timer value
|
||||||
* @param timeUnit
|
* @param timeUnit
|
||||||
* representing the unit of time to be used for timer.
|
* representing the unit of time to be used for timer.
|
||||||
*/
|
*/
|
||||||
@@ -257,16 +258,15 @@ public class JpaControllerManagement implements ControllerManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method calculates the time interval until the next event based
|
* This method calculates the time interval until the next event based on the
|
||||||
* on the desired number of events before the time when interval is
|
* desired number of events before the time when interval is reset to default.
|
||||||
* reset to default. The return value is bounded by
|
* The return value is bounded by {@link EventTimer#defaultEventInterval} and
|
||||||
* {@link EventTimer#defaultEventInterval} and
|
|
||||||
* {@link EventTimer#minimumEventInterval}.
|
* {@link EventTimer#minimumEventInterval}.
|
||||||
*
|
*
|
||||||
* @param eventCount
|
* @param eventCount
|
||||||
* number of events desired until the interval is reset to
|
* number of events desired until the interval is reset to default.
|
||||||
* default. This is not guaranteed as the interval between
|
* This is not guaranteed as the interval between events cannot be
|
||||||
* events cannot be less than the minimum interval
|
* less than the minimum interval
|
||||||
* @param timerResetTime
|
* @param timerResetTime
|
||||||
* time when exponential forwarding should reset to default
|
* time when exponential forwarding should reset to default
|
||||||
*
|
*
|
||||||
@@ -386,16 +386,25 @@ public class JpaControllerManagement implements ControllerManagement {
|
|||||||
@Transactional(isolation = Isolation.READ_COMMITTED)
|
@Transactional(isolation = Isolation.READ_COMMITTED)
|
||||||
@Retryable(include = ConcurrencyFailureException.class, exclude = EntityAlreadyExistsException.class, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
@Retryable(include = ConcurrencyFailureException.class, exclude = EntityAlreadyExistsException.class, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||||
public Target findOrRegisterTargetIfItDoesNotExist(final String controllerId, final URI address) {
|
public Target findOrRegisterTargetIfItDoesNotExist(final String controllerId, final URI address) {
|
||||||
|
return findOrRegisterTargetIfItDoesNotExist(controllerId, address, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(isolation = Isolation.READ_COMMITTED)
|
||||||
|
@Retryable(include = ConcurrencyFailureException.class, exclude = EntityAlreadyExistsException.class, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||||
|
public Target findOrRegisterTargetIfItDoesNotExist(final String controllerId, final URI address,
|
||||||
|
final String name) {
|
||||||
final Specification<JpaTarget> spec = (targetRoot, query, cb) -> cb
|
final Specification<JpaTarget> spec = (targetRoot, query, cb) -> cb
|
||||||
.equal(targetRoot.get(JpaTarget_.controllerId), controllerId);
|
.equal(targetRoot.get(JpaTarget_.controllerId), controllerId);
|
||||||
|
|
||||||
return targetRepository.findOne(spec).map(target -> updateTargetStatus(target, address))
|
return targetRepository.findOne(spec).map(target -> updateTarget(target, address, name))
|
||||||
.orElseGet(() -> createTarget(controllerId, address));
|
.orElseGet(() -> createTarget(controllerId, address, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Target createTarget(final String controllerId, final URI address) {
|
private Target createTarget(final String controllerId, final URI address, String name) {
|
||||||
|
|
||||||
final Target result = targetRepository.save((JpaTarget) entityFactory.target().create()
|
final Target result = targetRepository.save((JpaTarget) entityFactory.target().create()
|
||||||
.controllerId(controllerId).description("Plug and Play target: " + controllerId).name(controllerId)
|
.controllerId(controllerId).description("Plug and Play target: " + controllerId).name((StringUtils.hasText(name) ? name : controllerId))
|
||||||
.status(TargetUpdateStatus.REGISTERED).lastTargetQuery(System.currentTimeMillis())
|
.status(TargetUpdateStatus.REGISTERED).lastTargetQuery(System.currentTimeMillis())
|
||||||
.address(Optional.ofNullable(address).map(URI::toString).orElse(null)).build());
|
.address(Optional.ofNullable(address).map(URI::toString).orElse(null)).build());
|
||||||
|
|
||||||
@@ -458,9 +467,8 @@ public class JpaControllerManagement implements ControllerManagement {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets {@link Target#getLastTargetQuery()} by native SQL in order to avoid
|
* Sets {@link Target#getLastTargetQuery()} by native SQL in order to avoid
|
||||||
* raising opt lock revision as this update is not mission critical and in
|
* raising opt lock revision as this update is not mission critical and in fact
|
||||||
* fact only written by {@link ControllerManagement}, i.e. the target
|
* only written by {@link ControllerManagement}, i.e. the target itself.
|
||||||
* itself.
|
|
||||||
*/
|
*/
|
||||||
private void setLastTargetQuery(final String tenant, final long currentTimeMillis, final List<String> chunk) {
|
private void setLastTargetQuery(final String tenant, final long currentTimeMillis, final List<String> chunk) {
|
||||||
final Map<String, String> paramMapping = Maps.newHashMapWithExpectedSize(chunk.size());
|
final Map<String, String> paramMapping = Maps.newHashMapWithExpectedSize(chunk.size());
|
||||||
@@ -488,39 +496,40 @@ public class JpaControllerManagement implements ControllerManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores target directly to DB in case either {@link Target#getAddress()}
|
* Stores target directly to DB in case either {@link Target#getAddress()} or
|
||||||
* or {@link Target#getUpdateStatus()} changes or the buffer queue is full.
|
* {@link Target#getUpdateStatus()} or {@link Target#getName()} changes or the buffer queue is full.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private Target updateTargetStatus(final JpaTarget toUpdate, final URI address) {
|
private Target updateTarget(final JpaTarget toUpdate, final URI address, final String name) {
|
||||||
boolean storeEager = isStoreEager(toUpdate, address);
|
if (isStoreEager(toUpdate, address, name) || !queue.offer(new TargetPoll(toUpdate))) {
|
||||||
|
if (isAddressChanged(toUpdate.getAddress(), address)) {
|
||||||
if (TargetUpdateStatus.UNKNOWN == toUpdate.getUpdateStatus()) {
|
|
||||||
toUpdate.setUpdateStatus(TargetUpdateStatus.REGISTERED);
|
|
||||||
storeEager = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (storeEager || !queue.offer(new TargetPoll(toUpdate))) {
|
|
||||||
toUpdate.setAddress(address.toString());
|
toUpdate.setAddress(address.toString());
|
||||||
|
}
|
||||||
|
if (isNameChanged(toUpdate.getName(), name)) {
|
||||||
|
toUpdate.setName(name);
|
||||||
|
}
|
||||||
|
if (isStatusUnknown(toUpdate.getUpdateStatus())) {
|
||||||
|
toUpdate.setUpdateStatus(TargetUpdateStatus.REGISTERED);
|
||||||
|
}
|
||||||
toUpdate.setLastTargetQuery(System.currentTimeMillis());
|
toUpdate.setLastTargetQuery(System.currentTimeMillis());
|
||||||
|
|
||||||
afterCommit.afterCommit(() -> eventPublisherHolder.getEventPublisher()
|
afterCommit.afterCommit(() -> eventPublisherHolder.getEventPublisher()
|
||||||
.publishEvent(new TargetPollEvent(toUpdate, eventPublisherHolder.getApplicationId())));
|
.publishEvent(new TargetPollEvent(toUpdate, eventPublisherHolder.getApplicationId())));
|
||||||
|
|
||||||
return targetRepository.save(toUpdate);
|
return targetRepository.save(toUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
return toUpdate;
|
return toUpdate;
|
||||||
}
|
}
|
||||||
|
private boolean isStoreEager(final JpaTarget toUpdate, final URI address, final String name) {
|
||||||
private boolean isStoreEager(final JpaTarget toUpdate, final URI address) {
|
return repositoryProperties.isEagerPollPersistence() || isAddressChanged(toUpdate.getAddress(), address)
|
||||||
if (repositoryProperties.isEagerPollPersistence()) {
|
|| isNameChanged(toUpdate.getName(), name) || isStatusUnknown(toUpdate.getUpdateStatus());
|
||||||
return true;
|
|
||||||
} else if (toUpdate.getAddress() == null) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return !toUpdate.getAddress().equals(address);
|
|
||||||
}
|
}
|
||||||
|
private boolean isAddressChanged(final URI addressToUpdate, final URI address) {
|
||||||
|
return addressToUpdate == null || !addressToUpdate.equals(address);
|
||||||
|
}
|
||||||
|
private boolean isNameChanged(final String nameToUpdate, final String name) {
|
||||||
|
return StringUtils.hasText(name) && !nameToUpdate.equals(name);
|
||||||
|
}
|
||||||
|
private boolean isStatusUnknown(final TargetUpdateStatus statusToUpdate) {
|
||||||
|
return TargetUpdateStatus.UNKNOWN == statusToUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -596,8 +605,8 @@ public class JpaControllerManagement implements ControllerManagement {
|
|||||||
* ActionStatus updates are allowed mainly if the action is active. If the
|
* ActionStatus updates are allowed mainly if the action is active. If the
|
||||||
* action is not active we accept further status updates if permitted so by
|
* action is not active we accept further status updates if permitted so by
|
||||||
* repository configuration. In this case, only the values: Status.ERROR and
|
* repository configuration. In this case, only the values: Status.ERROR and
|
||||||
* Status.FINISHED are allowed. In the case of a DOWNLOAD_ONLY action, we
|
* Status.FINISHED are allowed. In the case of a DOWNLOAD_ONLY action, we accept
|
||||||
* accept status updates only once.
|
* status updates only once.
|
||||||
*/
|
*/
|
||||||
private boolean isUpdatingActionStatusAllowed(final JpaAction action, final JpaActionStatus actionStatus) {
|
private boolean isUpdatingActionStatusAllowed(final JpaAction action, final JpaActionStatus actionStatus) {
|
||||||
|
|
||||||
@@ -732,8 +741,8 @@ public class JpaControllerManagement implements ControllerManagement {
|
|||||||
final UpdateMode mode) {
|
final UpdateMode mode) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constraints on attribute keys & values are not validated by
|
* Constraints on attribute keys & values are not validated by EclipseLink.
|
||||||
* EclipseLink. Hence, they are validated here.
|
* Hence, they are validated here.
|
||||||
*/
|
*/
|
||||||
if (data.entrySet().stream().anyMatch(e -> !isAttributeEntryValid(e))) {
|
if (data.entrySet().stream().anyMatch(e -> !isAttributeEntryValid(e))) {
|
||||||
throw new InvalidTargetAttributeException();
|
throw new InvalidTargetAttributeException();
|
||||||
@@ -744,7 +753,6 @@ public class JpaControllerManagement implements ControllerManagement {
|
|||||||
|
|
||||||
// get the modifiable attribute map
|
// get the modifiable attribute map
|
||||||
final Map<String, String> controllerAttributes = target.getControllerAttributes();
|
final Map<String, String> controllerAttributes = target.getControllerAttributes();
|
||||||
|
|
||||||
final UpdateMode updateMode = mode != null ? mode : UpdateMode.MERGE;
|
final UpdateMode updateMode = mode != null ? mode : UpdateMode.MERGE;
|
||||||
switch (updateMode) {
|
switch (updateMode) {
|
||||||
case REMOVE:
|
case REMOVE:
|
||||||
@@ -811,8 +819,8 @@ public class JpaControllerManagement implements ControllerManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers retrieved status for given {@link Target} and {@link Action} if
|
* Registers retrieved status for given {@link Target} and {@link Action} if it
|
||||||
* it does not exist yet.
|
* does not exist yet.
|
||||||
*
|
*
|
||||||
* @param actionId
|
* @param actionId
|
||||||
* to the handle status for
|
* to the handle status for
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verifies that management get access react as specified on calls for non existing entities by means "
|
@Description("Verifies that management get access react as specified on calls for non existing entities by means "
|
||||||
+ "of Optional not present.")
|
+ "of Optional not present.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 1)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 1) })
|
||||||
public void nonExistingEntityAccessReturnsNotPresent() {
|
public void nonExistingEntityAccessReturnsNotPresent() {
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
final SoftwareModule module = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule module = testdataFactory.createSoftwareModuleOs();
|
||||||
@@ -113,8 +113,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verifies that management queries react as specified on calls for non existing entities "
|
@Description("Verifies that management queries react as specified on calls for non existing entities "
|
||||||
+ " by means of throwing EntityNotFoundException.")
|
+ " by means of throwing EntityNotFoundException.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 1)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 1) })
|
||||||
public void entityQueriesReferringToNotExistingEntitiesThrowsException() throws URISyntaxException {
|
public void entityQueriesReferringToNotExistingEntitiesThrowsException() throws URISyntaxException {
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
final SoftwareModule module = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule module = testdataFactory.createSoftwareModuleOs();
|
||||||
@@ -149,13 +149,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Controller confirms successful update with FINISHED status.")
|
@Description("Controller confirms successful update with FINISHED status.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerConfirmsUpdateWithFinished() {
|
public void controllerConfirmsUpdateWithFinished() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
@@ -172,11 +172,11 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Controller confirmation fails with invalid messages.")
|
@Description("Controller confirmation fails with invalid messages.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerConfirmationFailsWithInvalidMessages() {
|
public void controllerConfirmationFailsWithInvalidMessages() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
@@ -200,14 +200,14 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Controller confirms successful update with FINISHED status on a action that is on canceling. "
|
@Description("Controller confirms successful update with FINISHED status on a action that is on canceling. "
|
||||||
+ "Reason: The decision to ignore the cancellation is in fact up to the controller.")
|
+ "Reason: The decision to ignore the cancellation is in fact up to the controller.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerConfirmsUpdateWithFinishedAndIgnoresCancellationWithThat() {
|
public void controllerConfirmsUpdateWithFinishedAndIgnoresCancellationWithThat() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
deploymentManagement.cancelAction(actionId);
|
deploymentManagement.cancelAction(actionId);
|
||||||
@@ -223,11 +223,11 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Update server rejects cancellation feedback if action is not in CANCELING state.")
|
@Description("Update server rejects cancellation feedback if action is not in CANCELING state.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void cancellationFeedbackRejectedIfActionIsNotInCanceling() {
|
public void cancellationFeedbackRejectedIfActionIsNotInCanceling() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
@@ -245,13 +245,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Controller confirms action cancellation with FINISHED status.")
|
@Description("Controller confirms action cancellation with FINISHED status.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerConfirmsActionCancellationWithFinished() {
|
public void controllerConfirmsActionCancellationWithFinished() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
@@ -272,13 +272,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Controller confirms action cancellation with FINISHED status.")
|
@Description("Controller confirms action cancellation with FINISHED status.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerConfirmsActionCancellationWithCanceled() {
|
public void controllerConfirmsActionCancellationWithCanceled() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
@@ -300,13 +300,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Controller rejects action cancellation with CANCEL_REJECTED status. Action goes back to RUNNING status as it expects "
|
@Description("Controller rejects action cancellation with CANCEL_REJECTED status. Action goes back to RUNNING status as it expects "
|
||||||
+ "that the controller will continue the original update.")
|
+ "that the controller will continue the original update.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerRejectsActionCancellationWithReject() {
|
public void controllerRejectsActionCancellationWithReject() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
@@ -328,13 +328,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Controller rejects action cancellation with ERROR status. Action goes back to RUNNING status as it expects "
|
@Description("Controller rejects action cancellation with ERROR status. Action goes back to RUNNING status as it expects "
|
||||||
+ "that the controller will continue the original update.")
|
+ "that the controller will continue the original update.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerRejectsActionCancellationWithError() {
|
public void controllerRejectsActionCancellationWithError() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
@@ -465,12 +465,12 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verifies that assignment verification works based on SHA1 hash. By design it is not important which artifact "
|
@Description("Verifies that assignment verification works based on SHA1 hash. By design it is not important which artifact "
|
||||||
+ "is actually used for the check as long as they have an identical binary, i.e. same SHA1 hash. ")
|
+ "is actually used for the check as long as they have an identical binary, i.e. same SHA1 hash. ")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
|
||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 2)})
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 2) })
|
||||||
public void hasTargetArtifactAssignedIsTrueWithMultipleArtifacts() {
|
public void hasTargetArtifactAssignedIsTrueWithMultipleArtifacts() {
|
||||||
final int artifactSize = 5 * 1024;
|
final int artifactSize = 5 * 1024;
|
||||||
final byte[] random = RandomUtils.nextBytes(artifactSize);
|
final byte[] random = RandomUtils.nextBytes(artifactSize);
|
||||||
@@ -500,7 +500,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Register a controller which does not exist")
|
@Description("Register a controller which does not exist")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 2)})
|
@Expect(type = TargetPollEvent.class, count = 2)})
|
||||||
public void findOrRegisterTargetIfItDoesNotExist() {
|
public void findOrRegisterTargetIfItDoesNotExist() {
|
||||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
||||||
@@ -511,6 +511,20 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
assertThat(targetRepository.count()).as("Only 1 target should be registered").isEqualTo(1L);
|
assertThat(targetRepository.count()).as("Only 1 target should be registered").isEqualTo(1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Register a controller with name which does not exist and update its name")
|
||||||
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
|
@Expect(type = TargetPollEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 1) })
|
||||||
|
public void findOrRegisterTargetIfItDoesNotExistWithName() {
|
||||||
|
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST, "TestName");
|
||||||
|
final Target sameTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST,
|
||||||
|
"ChangedTestName");
|
||||||
|
assertThat(target.getId()).as("Target should be the equals").isEqualTo(sameTarget.getId());
|
||||||
|
assertThat(target.getName()).as("Taget names should be different").isNotEqualTo(sameTarget.getName());
|
||||||
|
assertThat(sameTarget.getName()).as("Taget name should be changed").isEqualTo("ChangedTestName");
|
||||||
|
assertThat(targetRepository.count()).as("Only 1 target should be registred").isEqualTo(1L);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tries to register a target with an invalid controller id")
|
@Description("Tries to register a target with an invalid controller id")
|
||||||
public void findOrRegisterTargetIfItDoesNotExistThrowsExceptionForInvalidControllerIdParam() {
|
public void findOrRegisterTargetIfItDoesNotExistThrowsExceptionForInvalidControllerIdParam() {
|
||||||
@@ -556,8 +570,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Register a controller which does not exist, when a ConcurrencyFailureException is raised, the "
|
@Description("Register a controller which does not exist, when a ConcurrencyFailureException is raised, the "
|
||||||
+ "exception is not rethrown when the max retries are not yet reached")
|
+ "exception is not rethrown when the max retries are not yet reached")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 1)})
|
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void findOrRegisterTargetIfItDoesNotExistDoesNotThrowExceptionBeforeMaxRetries() {
|
public void findOrRegisterTargetIfItDoesNotExistDoesNotThrowExceptionBeforeMaxRetries() {
|
||||||
|
|
||||||
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
|
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
|
||||||
@@ -580,6 +594,28 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Register a controller which does not exist, then update the controller twice, first time by providing a name property and second time without a new name")
|
||||||
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
|
@Expect(type = TargetPollEvent.class, count = 3) ,
|
||||||
|
@Expect(type = TargetUpdatedEvent.class, count = 1)})
|
||||||
|
public void findOrRegisterTargetIfItDoesNotExistDoesUpdateNameOnExistingTargetProperly() {
|
||||||
|
|
||||||
|
String controllerId = "12345";
|
||||||
|
String targetName = "UpdatedName";
|
||||||
|
|
||||||
|
final Target newTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId, LOCALHOST);
|
||||||
|
assertThat(newTarget.getName()).isEqualTo(controllerId);
|
||||||
|
|
||||||
|
|
||||||
|
Target firstTimeUpdatedTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId, LOCALHOST, targetName);
|
||||||
|
assertThat(firstTimeUpdatedTarget.getName()).isEqualTo(targetName);
|
||||||
|
|
||||||
|
//Name should not change to default (name=targetId) if target is updated without new name provided
|
||||||
|
Target secondTimeUpdatedTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId, LOCALHOST);
|
||||||
|
assertThat(secondTimeUpdatedTarget.getName()).isEqualTo(targetName);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Register a controller which does not exist, if a EntityAlreadyExistsException is raised, the "
|
@Description("Register a controller which does not exist, if a EntityAlreadyExistsException is raised, the "
|
||||||
+ "exception is rethrown and no further retries will be attempted")
|
+ "exception is rethrown and no further retries will be attempted")
|
||||||
@@ -629,9 +665,9 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that targetVisible metadata is returned from repository")
|
@Description("Verify that targetVisible metadata is returned from repository")
|
||||||
@ExpectEvents({@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6)})
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6) })
|
||||||
public void findTargetVisibleMetaDataBySoftwareModuleId() {
|
public void findTargetVisibleMetaDataBySoftwareModuleId() {
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet();
|
final DistributionSet set = testdataFactory.createDistributionSet();
|
||||||
testdataFactory.addSoftwareModuleMetadata(set);
|
testdataFactory.addSoftwareModuleMetadata(set);
|
||||||
@@ -646,8 +682,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that controller registration does not result in a TargetPollEvent if feature is disabled")
|
@Description("Verify that controller registration does not result in a TargetPollEvent if feature is disabled")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 0)})
|
@Expect(type = TargetPollEvent.class, count = 0) })
|
||||||
public void targetPollEventNotSendIfDisabled() {
|
public void targetPollEventNotSendIfDisabled() {
|
||||||
repositoryProperties.setPublishTargetPollEvent(false);
|
repositoryProperties.setPublishTargetPollEvent(false);
|
||||||
controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
||||||
@@ -656,12 +692,12 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Controller tries to finish an update process after it has been finished by an error action status.")
|
@Description("Controller tries to finish an update process after it has been finished by an error action status.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void tryToFinishWithErrorUpdateProcessMoreThanOnce() {
|
public void tryToFinishWithErrorUpdateProcessMoreThanOnce() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
@@ -702,13 +738,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Controller tries to finish an update process after it has been finished by an FINISHED action status.")
|
@Description("Controller tries to finish an update process after it has been finished by an FINISHED action status.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void tryToFinishUpdateProcessMoreThanOnce() {
|
public void tryToFinishUpdateProcessMoreThanOnce() {
|
||||||
final Long actionId = prepareFinishedUpdate().getId();
|
final Long actionId = prepareFinishedUpdate().getId();
|
||||||
|
|
||||||
@@ -739,13 +775,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Controller tries to send an update feedback after it has been finished which is reject as the repository is "
|
@Description("Controller tries to send an update feedback after it has been finished which is reject as the repository is "
|
||||||
+ "configured to reject that.")
|
+ "configured to reject that.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void sendUpdatesForFinishUpdateProcessDroppedIfDisabled() {
|
public void sendUpdatesForFinishUpdateProcessDroppedIfDisabled() {
|
||||||
repositoryProperties.setRejectActionStatusForClosedAction(true);
|
repositoryProperties.setRejectActionStatusForClosedAction(true);
|
||||||
|
|
||||||
@@ -766,13 +802,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Controller tries to send an update feedback after it has been finished which is accepted as the repository is "
|
@Description("Controller tries to send an update feedback after it has been finished which is accepted as the repository is "
|
||||||
+ "configured to accept them.")
|
+ "configured to accept them.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void sendUpdatesForFinishUpdateProcessAcceptedIfEnabled() {
|
public void sendUpdatesForFinishUpdateProcessAcceptedIfEnabled() {
|
||||||
repositoryProperties.setRejectActionStatusForClosedAction(false);
|
repositoryProperties.setRejectActionStatusForClosedAction(false);
|
||||||
|
|
||||||
@@ -792,8 +828,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target attribute update is reflected by the repository.")
|
@Description("Ensures that target attribute update is reflected by the repository.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 3)})
|
@Expect(type = TargetUpdatedEvent.class, count = 3) })
|
||||||
public void updateTargetAttributes() throws Exception {
|
public void updateTargetAttributes() throws Exception {
|
||||||
final String controllerId = "test123";
|
final String controllerId = "test123";
|
||||||
final Target target = testdataFactory.createTarget(controllerId);
|
final Target target = testdataFactory.createTarget(controllerId);
|
||||||
@@ -848,8 +884,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target attributes can be updated using different update modes.")
|
@Description("Ensures that target attributes can be updated using different update modes.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 4)})
|
@Expect(type = TargetUpdatedEvent.class, count = 4) })
|
||||||
public void updateTargetAttributesWithDifferentUpdateModes() {
|
public void updateTargetAttributesWithDifferentUpdateModes() {
|
||||||
|
|
||||||
final String controllerId = "testCtrl";
|
final String controllerId = "testCtrl";
|
||||||
@@ -946,8 +982,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target attribute update fails if quota hits.")
|
@Description("Ensures that target attribute update fails if quota hits.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2)})
|
@Expect(type = TargetUpdatedEvent.class, count = 2) })
|
||||||
public void updateTargetAttributesFailsIfTooManyEntries() throws Exception {
|
public void updateTargetAttributesFailsIfTooManyEntries() throws Exception {
|
||||||
final String controllerId = "test123";
|
final String controllerId = "test123";
|
||||||
final int allowedAttributes = quotaManagement.getMaxAttributeEntriesPerTarget();
|
final int allowedAttributes = quotaManagement.getMaxAttributeEntriesPerTarget();
|
||||||
@@ -1025,11 +1061,11 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Controller providing status entries fails if providing more than permitted by quota.")
|
@Description("Controller providing status entries fails if providing more than permitted by quota.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerProvidesIntermediateFeedbackFailsIfQuotaHit() {
|
public void controllerProvidesIntermediateFeedbackFailsIfQuotaHit() {
|
||||||
final int allowStatusEntries = 10;
|
final int allowStatusEntries = 10;
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
@@ -1073,11 +1109,11 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that the quota specifying the maximum number of status entries per action is enforced.")
|
@Description("Verifies that the quota specifying the maximum number of status entries per action is enforced.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 2),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 2),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6) })
|
||||||
public void addActionStatusUpdatesUntilQuotaIsExceeded() {
|
public void addActionStatusUpdatesUntilQuotaIsExceeded() {
|
||||||
|
|
||||||
// any distribution set assignment causes 1 status entity to be created
|
// any distribution set assignment causes 1 status entity to be created
|
||||||
@@ -1109,11 +1145,11 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that the quota specifying the maximum number of messages per action status is enforced.")
|
@Description("Verifies that the quota specifying the maximum number of messages per action status is enforced.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void createActionStatusWithTooManyMessages() {
|
public void createActionStatusWithTooManyMessages() {
|
||||||
|
|
||||||
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
||||||
@@ -1137,11 +1173,11 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that a DOWNLOAD_ONLY action is not marked complete when the controller reports DOWNLOAD")
|
@Description("Verifies that a DOWNLOAD_ONLY action is not marked complete when the controller reports DOWNLOAD")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerReportsDownloadForDownloadOnlyAction() {
|
public void controllerReportsDownloadForDownloadOnlyAction() {
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
||||||
@@ -1158,13 +1194,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that a DOWNLOAD_ONLY action is marked complete once the controller reports DOWNLOADED")
|
@Description("Verifies that a DOWNLOAD_ONLY action is marked complete once the controller reports DOWNLOADED")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerReportsDownloadedForDownloadOnlyAction() {
|
public void controllerReportsDownloadedForDownloadOnlyAction() {
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
||||||
@@ -1181,13 +1217,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that a controller can report a FINISHED event for a DOWNLOAD_ONLY non-active action.")
|
@Description("Verifies that a controller can report a FINISHED event for a DOWNLOAD_ONLY non-active action.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 3),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 3),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 2),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 2),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 2),
|
@Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerReportsActionFinishedForDownloadOnlyActionThatIsNotActive() {
|
public void controllerReportsActionFinishedForDownloadOnlyActionThatIsNotActive() {
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
||||||
@@ -1204,13 +1240,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that multiple DOWNLOADED events for a DOWNLOAD_ONLY action are handled.")
|
@Description("Verifies that multiple DOWNLOADED events for a DOWNLOAD_ONLY action are handled.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 3),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 3),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerReportsMultipleDownloadedForDownloadOnlyAction() {
|
public void controllerReportsMultipleDownloadedForDownloadOnlyAction() {
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
||||||
@@ -1229,13 +1265,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test(expected = QuotaExceededException.class)
|
@Test(expected = QuotaExceededException.class)
|
||||||
@Description("Verifies that quota is asserted when a controller reports too many DOWNLOADED events for a "
|
@Description("Verifies that quota is asserted when a controller reports too many DOWNLOADED events for a "
|
||||||
+ "DOWNLOAD_ONLY action.")
|
+ "DOWNLOAD_ONLY action.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 9),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 9),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void quotaExceptionWhencontrollerReportsTooManyDownloadedMessagesForDownloadOnlyAction() {
|
public void quotaExceptionWhencontrollerReportsTooManyDownloadedMessagesForDownloadOnlyAction() {
|
||||||
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
@@ -1248,13 +1284,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that quota is enforced for UpdateActionStatus events for DOWNLOAD_ONLY assignments.")
|
@Description("Verifies that quota is enforced for UpdateActionStatus events for DOWNLOAD_ONLY assignments.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 9),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 9),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForDownloadOnlyAction() {
|
public void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForDownloadOnlyAction() {
|
||||||
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
@@ -1279,11 +1315,11 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that quota is enforced for UpdateActionStatus events for FORCED assignments.")
|
@Description("Verifies that quota is enforced for UpdateActionStatus events for FORCED assignments.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForForced() {
|
public void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForForced() {
|
||||||
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
@@ -1344,13 +1380,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verifies that a target can report FINISHED/ERROR updates for DOWNLOAD_ONLY assignments regardless of "
|
@Description("Verifies that a target can report FINISHED/ERROR updates for DOWNLOAD_ONLY assignments regardless of "
|
||||||
+ "repositoryProperties.rejectActionStatusForClosedAction value.")
|
+ "repositoryProperties.rejectActionStatusForClosedAction value.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 4),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 4),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 4), @Expect(type = TargetUpdatedEvent.class, count = 12),
|
@Expect(type = ActionCreatedEvent.class, count = 4), @Expect(type = TargetUpdatedEvent.class, count = 12),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 4),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 4),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 6),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 6),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 8),
|
@Expect(type = ActionUpdatedEvent.class, count = 8),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 12)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 12) })
|
||||||
public void targetCanAlwaysReportFinishedOrErrorAfterActionIsClosedForDownloadOnlyAssignments() {
|
public void targetCanAlwaysReportFinishedOrErrorAfterActionIsClosedForDownloadOnlyAssignments() {
|
||||||
|
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
@@ -1395,13 +1431,13 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verifies that a controller can report a FINISHED event for a DOWNLOAD_ONLY action after having"
|
@Description("Verifies that a controller can report a FINISHED event for a DOWNLOAD_ONLY action after having"
|
||||||
+ " installed an intermediate update.")
|
+ " installed an intermediate update.")
|
||||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
|
||||||
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 5),
|
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 5),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 3),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 3),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 3),
|
@Expect(type = ActionUpdatedEvent.class, count = 3),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6)})
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6) })
|
||||||
public void controllerReportsFinishedForOldDownloadOnlyActionAfterSuccessfulForcedAssignment() {
|
public void controllerReportsFinishedForOldDownloadOnlyActionAfterSuccessfulForcedAssignment() {
|
||||||
|
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
|
|||||||
@@ -117,8 +117,8 @@ public class TestdataFactory {
|
|||||||
public static final String SM_TYPE_RT = "runtime";
|
public static final String SM_TYPE_RT = "runtime";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key of test "application" {@link SoftwareModuleType} : optional software
|
* Key of test "application" {@link SoftwareModuleType} : optional software in
|
||||||
* in {@link #DS_TYPE_DEFAULT}.
|
* {@link #DS_TYPE_DEFAULT}.
|
||||||
*/
|
*/
|
||||||
public static final String SM_TYPE_APP = "application";
|
public static final String SM_TYPE_APP = "application";
|
||||||
|
|
||||||
@@ -160,14 +160,13 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link DistributionSet} in repository including three
|
* Creates {@link DistributionSet} in repository including three
|
||||||
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
|
||||||
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
|
* {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
|
||||||
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
|
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix
|
||||||
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
|
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
|
||||||
* vendor and description.
|
* vendor and description.
|
||||||
*
|
|
||||||
* @return {@link DistributionSet} entity.
|
* @return {@link DistributionSet} entity.
|
||||||
*/
|
*/
|
||||||
public DistributionSet createDistributionSet(final String prefix) {
|
public DistributionSet createDistributionSet(final String prefix) {
|
||||||
@@ -176,8 +175,8 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link DistributionSet} in repository including three
|
* Creates {@link DistributionSet} in repository including three
|
||||||
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
|
||||||
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
|
* {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
|
||||||
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
|
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
|
||||||
*
|
*
|
||||||
* @return {@link DistributionSet} entity.
|
* @return {@link DistributionSet} entity.
|
||||||
@@ -188,13 +187,12 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link DistributionSet} in repository including three
|
* Creates {@link DistributionSet} in repository including three
|
||||||
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
|
||||||
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
|
* {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
|
||||||
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
|
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
|
||||||
*
|
*
|
||||||
* @param modules
|
* @param modules
|
||||||
* of {@link DistributionSet#getModules()}
|
* of {@link DistributionSet#getModules()}
|
||||||
*
|
|
||||||
* @return {@link DistributionSet} entity.
|
* @return {@link DistributionSet} entity.
|
||||||
*/
|
*/
|
||||||
public DistributionSet createDistributionSet(final Collection<SoftwareModule> modules) {
|
public DistributionSet createDistributionSet(final Collection<SoftwareModule> modules) {
|
||||||
@@ -203,8 +201,8 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link DistributionSet} in repository including three
|
* Creates {@link DistributionSet} in repository including three
|
||||||
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
|
||||||
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
|
* {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
|
||||||
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
|
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
|
||||||
*
|
*
|
||||||
* @param modules
|
* @param modules
|
||||||
@@ -212,7 +210,6 @@ public class TestdataFactory {
|
|||||||
* @param prefix
|
* @param prefix
|
||||||
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
|
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
|
||||||
* vendor and description.
|
* vendor and description.
|
||||||
*
|
|
||||||
* @return {@link DistributionSet} entity.
|
* @return {@link DistributionSet} entity.
|
||||||
*/
|
*/
|
||||||
public DistributionSet createDistributionSet(final Collection<SoftwareModule> modules, final String prefix) {
|
public DistributionSet createDistributionSet(final Collection<SoftwareModule> modules, final String prefix) {
|
||||||
@@ -221,15 +218,14 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link DistributionSet} in repository including three
|
* Creates {@link DistributionSet} in repository including three
|
||||||
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
|
||||||
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION}.
|
* {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION}.
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix
|
||||||
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
|
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
|
||||||
* vendor and description.
|
* vendor and description.
|
||||||
* @param isRequiredMigrationStep
|
* @param isRequiredMigrationStep
|
||||||
* for {@link DistributionSet#isRequiredMigrationStep()}
|
* for {@link DistributionSet#isRequiredMigrationStep()}
|
||||||
*
|
|
||||||
* @return {@link DistributionSet} entity.
|
* @return {@link DistributionSet} entity.
|
||||||
*/
|
*/
|
||||||
public DistributionSet createDistributionSet(final String prefix, final boolean isRequiredMigrationStep) {
|
public DistributionSet createDistributionSet(final String prefix, final boolean isRequiredMigrationStep) {
|
||||||
@@ -238,8 +234,8 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link DistributionSet} in repository including three
|
* Creates {@link DistributionSet} in repository including three
|
||||||
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
|
||||||
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
|
* {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
|
||||||
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
|
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix
|
||||||
@@ -247,7 +243,6 @@ public class TestdataFactory {
|
|||||||
* vendor and description.
|
* vendor and description.
|
||||||
* @param tags
|
* @param tags
|
||||||
* {@link DistributionSet#getTags()}
|
* {@link DistributionSet#getTags()}
|
||||||
*
|
|
||||||
* @return {@link DistributionSet} entity.
|
* @return {@link DistributionSet} entity.
|
||||||
*/
|
*/
|
||||||
public DistributionSet createDistributionSet(final String prefix, final Collection<DistributionSetTag> tags) {
|
public DistributionSet createDistributionSet(final String prefix, final Collection<DistributionSetTag> tags) {
|
||||||
@@ -256,19 +251,17 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link DistributionSet} in repository including three
|
* Creates {@link DistributionSet} in repository including three
|
||||||
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
|
||||||
* , {@link #SM_TYPE_APP}.
|
* {@link #SM_TYPE_APP}.
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix
|
||||||
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
|
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
|
||||||
* vendor and description.
|
* vendor and description.
|
||||||
* @param version
|
* @param version
|
||||||
* {@link DistributionSet#getVersion()} and
|
* {@link DistributionSet#getVersion()} and
|
||||||
* {@link SoftwareModule#getVersion()} extended by a random
|
* {@link SoftwareModule#getVersion()} extended by a random number.
|
||||||
* number.
|
|
||||||
* @param isRequiredMigrationStep
|
* @param isRequiredMigrationStep
|
||||||
* for {@link DistributionSet#isRequiredMigrationStep()}
|
* for {@link DistributionSet#isRequiredMigrationStep()}
|
||||||
*
|
|
||||||
* @return {@link DistributionSet} entity.
|
* @return {@link DistributionSet} entity.
|
||||||
*/
|
*/
|
||||||
public DistributionSet createDistributionSet(final String prefix, final String version,
|
public DistributionSet createDistributionSet(final String prefix, final String version,
|
||||||
@@ -326,13 +319,11 @@ public class TestdataFactory {
|
|||||||
* vendor and description.
|
* vendor and description.
|
||||||
* @param version
|
* @param version
|
||||||
* {@link DistributionSet#getVersion()} and
|
* {@link DistributionSet#getVersion()} and
|
||||||
* {@link SoftwareModule#getVersion()} extended by a random
|
* {@link SoftwareModule#getVersion()} extended by a random number.
|
||||||
* number.
|
|
||||||
* @param isRequiredMigrationStep
|
* @param isRequiredMigrationStep
|
||||||
* for {@link DistributionSet#isRequiredMigrationStep()}
|
* for {@link DistributionSet#isRequiredMigrationStep()}
|
||||||
* @param modules
|
* @param modules
|
||||||
* for {@link DistributionSet#getModules()}
|
* for {@link DistributionSet#getModules()}
|
||||||
*
|
|
||||||
* @return {@link DistributionSet} entity.
|
* @return {@link DistributionSet} entity.
|
||||||
*/
|
*/
|
||||||
public DistributionSet createDistributionSet(final String prefix, final String version,
|
public DistributionSet createDistributionSet(final String prefix, final String version,
|
||||||
@@ -347,8 +338,8 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link DistributionSet} in repository including three
|
* Creates {@link DistributionSet} in repository including three
|
||||||
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
|
||||||
* , {@link #SM_TYPE_APP}.
|
* {@link #SM_TYPE_APP}.
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix
|
||||||
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
|
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
|
||||||
@@ -359,7 +350,6 @@ public class TestdataFactory {
|
|||||||
* number.updat
|
* number.updat
|
||||||
* @param tags
|
* @param tags
|
||||||
* {@link DistributionSet#getTags()}
|
* {@link DistributionSet#getTags()}
|
||||||
*
|
|
||||||
* @return {@link DistributionSet} entity.
|
* @return {@link DistributionSet} entity.
|
||||||
*/
|
*/
|
||||||
public DistributionSet createDistributionSet(final String prefix, final String version,
|
public DistributionSet createDistributionSet(final String prefix, final String version,
|
||||||
@@ -375,14 +365,13 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link DistributionSet}s in repository including three
|
* Creates {@link DistributionSet}s in repository including three
|
||||||
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
|
||||||
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} followed by an
|
* {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} followed by an iterative
|
||||||
* iterative number and {@link DistributionSet#isRequiredMigrationStep()}
|
* number and {@link DistributionSet#isRequiredMigrationStep()}
|
||||||
* <code>false</code>.
|
* <code>false</code>.
|
||||||
*
|
*
|
||||||
* @param number
|
* @param number
|
||||||
* of {@link DistributionSet}s to create
|
* of {@link DistributionSet}s to create
|
||||||
*
|
|
||||||
* @return {@link List} of {@link DistributionSet} entities
|
* @return {@link List} of {@link DistributionSet} entities
|
||||||
*/
|
*/
|
||||||
public List<DistributionSet> createDistributionSets(final int number) {
|
public List<DistributionSet> createDistributionSets(final int number) {
|
||||||
@@ -391,8 +380,7 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a list of {@link DistributionSet}s without modules, i.e.
|
* Create a list of {@link DistributionSet}s without modules, i.e. incomplete.
|
||||||
* incomplete.
|
|
||||||
*
|
*
|
||||||
* @param number
|
* @param number
|
||||||
* of {@link DistributionSet}s to create
|
* of {@link DistributionSet}s to create
|
||||||
@@ -412,9 +400,9 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link DistributionSet}s in repository including three
|
* Creates {@link DistributionSet}s in repository including three
|
||||||
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
|
||||||
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} followed by an
|
* {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} followed by an iterative
|
||||||
* iterative number and {@link DistributionSet#isRequiredMigrationStep()}
|
* number and {@link DistributionSet#isRequiredMigrationStep()}
|
||||||
* <code>false</code>.
|
* <code>false</code>.
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix
|
||||||
@@ -422,7 +410,6 @@ public class TestdataFactory {
|
|||||||
* vendor and description.
|
* vendor and description.
|
||||||
* @param number
|
* @param number
|
||||||
* of {@link DistributionSet}s to create
|
* of {@link DistributionSet}s to create
|
||||||
*
|
|
||||||
* @return {@link List} of {@link DistributionSet} entities
|
* @return {@link List} of {@link DistributionSet} entities
|
||||||
*/
|
*/
|
||||||
public List<DistributionSet> createDistributionSets(final String prefix, final int number) {
|
public List<DistributionSet> createDistributionSets(final String prefix, final int number) {
|
||||||
@@ -444,7 +431,6 @@ public class TestdataFactory {
|
|||||||
* {@link DistributionSet#getName()}
|
* {@link DistributionSet#getName()}
|
||||||
* @param version
|
* @param version
|
||||||
* {@link DistributionSet#getVersion()}
|
* {@link DistributionSet#getVersion()}
|
||||||
*
|
|
||||||
* @return {@link DistributionSet} entity
|
* @return {@link DistributionSet} entity
|
||||||
*/
|
*/
|
||||||
public DistributionSet createDistributionSetWithNoSoftwareModules(final String name, final String version) {
|
public DistributionSet createDistributionSetWithNoSoftwareModules(final String name, final String version) {
|
||||||
@@ -454,12 +440,11 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link Artifact}s for given {@link SoftwareModule} with a small
|
* Creates {@link Artifact}s for given {@link SoftwareModule} with a small text
|
||||||
* text payload.
|
* payload.
|
||||||
*
|
*
|
||||||
* @param moduleId
|
* @param moduleId
|
||||||
* the {@link Artifact}s belong to.
|
* the {@link Artifact}s belong to.
|
||||||
*
|
|
||||||
* @return {@link Artifact} entity.
|
* @return {@link Artifact} entity.
|
||||||
*/
|
*/
|
||||||
public List<Artifact> createArtifacts(final Long moduleId) {
|
public List<Artifact> createArtifacts(final Long moduleId) {
|
||||||
@@ -473,18 +458,15 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an {@link Artifact} for given {@link SoftwareModule} with a small
|
* Create an {@link Artifact} for given {@link SoftwareModule} with a small text
|
||||||
* text payload.
|
* payload.
|
||||||
*
|
*
|
||||||
* @param artifactData
|
* @param artifactData
|
||||||
* the {@link Artifact} Inputstream
|
* the {@link Artifact} Inputstream
|
||||||
*
|
|
||||||
* @param moduleId
|
* @param moduleId
|
||||||
* the {@link Artifact} belongs to
|
* the {@link Artifact} belongs to
|
||||||
*
|
|
||||||
* @param filename
|
* @param filename
|
||||||
* that was provided during upload.
|
* that was provided during upload.
|
||||||
*
|
|
||||||
* @return {@link Artifact} entity.
|
* @return {@link Artifact} entity.
|
||||||
*/
|
*/
|
||||||
public Artifact createArtifact(final String artifactData, final Long moduleId, final String filename) {
|
public Artifact createArtifact(final String artifactData, final Long moduleId, final String filename) {
|
||||||
@@ -494,36 +476,32 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an {@link Artifact} for given {@link SoftwareModule} with a small
|
* Create an {@link Artifact} for given {@link SoftwareModule} with a small text
|
||||||
* text payload.
|
* payload.
|
||||||
*
|
*
|
||||||
* @param artifactData
|
* @param artifactData
|
||||||
* the {@link Artifact} Inputstream
|
* the {@link Artifact} Inputstream
|
||||||
*
|
|
||||||
* @param moduleId
|
* @param moduleId
|
||||||
* the {@link Artifact} belongs to
|
* the {@link Artifact} belongs to
|
||||||
*
|
|
||||||
* @param filename
|
* @param filename
|
||||||
* that was provided during upload.
|
* that was provided during upload.
|
||||||
*
|
|
||||||
* @param fileSize
|
* @param fileSize
|
||||||
* the file size
|
* the file size
|
||||||
*
|
|
||||||
* @return {@link Artifact} entity.
|
* @return {@link Artifact} entity.
|
||||||
*/
|
*/
|
||||||
public Artifact createArtifact(final byte[] artifactData, final Long moduleId, final String filename, final int fileSize) {
|
public Artifact createArtifact(final byte[] artifactData, final Long moduleId, final String filename,
|
||||||
return artifactManagement
|
final int fileSize) {
|
||||||
.create(new ArtifactUpload(new ByteArrayInputStream(artifactData), moduleId, filename, false, fileSize));
|
return artifactManagement.create(
|
||||||
|
new ArtifactUpload(new ByteArrayInputStream(artifactData), moduleId, filename, false, fileSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link SoftwareModule} with {@link #DEFAULT_VENDOR} and
|
* Creates {@link SoftwareModule} with {@link #DEFAULT_VENDOR} and
|
||||||
* {@link #DEFAULT_VERSION} and random generated
|
* {@link #DEFAULT_VERSION} and random generated {@link Target#getDescription()}
|
||||||
* {@link Target#getDescription()} in the repository.
|
* in the repository.
|
||||||
*
|
*
|
||||||
* @param typeKey
|
* @param typeKey
|
||||||
* of the {@link SoftwareModuleType}
|
* of the {@link SoftwareModuleType}
|
||||||
*
|
|
||||||
* @return persisted {@link SoftwareModule}.
|
* @return persisted {@link SoftwareModule}.
|
||||||
*/
|
*/
|
||||||
public SoftwareModule createSoftwareModule(final String typeKey) {
|
public SoftwareModule createSoftwareModule(final String typeKey) {
|
||||||
@@ -531,11 +509,9 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link SoftwareModule} of type
|
* Creates {@link SoftwareModule} of type {@value Constants#SMT_DEFAULT_APP_KEY}
|
||||||
* {@value Constants#SMT_DEFAULT_APP_KEY} with {@link #DEFAULT_VENDOR} and
|
* with {@link #DEFAULT_VENDOR} and {@link #DEFAULT_VERSION} and random
|
||||||
* {@link #DEFAULT_VERSION} and random generated
|
* generated {@link Target#getDescription()} in the repository.
|
||||||
* {@link Target#getDescription()} in the repository.
|
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* @return persisted {@link SoftwareModule}.
|
* @return persisted {@link SoftwareModule}.
|
||||||
*/
|
*/
|
||||||
@@ -544,15 +520,12 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link SoftwareModule} of type
|
* Creates {@link SoftwareModule} of type {@value Constants#SMT_DEFAULT_APP_KEY}
|
||||||
* {@value Constants#SMT_DEFAULT_APP_KEY} with {@link #DEFAULT_VENDOR} and
|
* with {@link #DEFAULT_VENDOR} and {@link #DEFAULT_VERSION} and random
|
||||||
* {@link #DEFAULT_VERSION} and random generated
|
* generated {@link Target#getDescription()} in the repository.
|
||||||
* {@link Target#getDescription()} in the repository.
|
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix
|
||||||
* added to name and version
|
* added to name and version
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return persisted {@link SoftwareModule}.
|
* @return persisted {@link SoftwareModule}.
|
||||||
*/
|
*/
|
||||||
public SoftwareModule createSoftwareModuleApp(final String prefix) {
|
public SoftwareModule createSoftwareModuleApp(final String prefix) {
|
||||||
@@ -560,11 +533,9 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link SoftwareModule} of type
|
* Creates {@link SoftwareModule} of type {@value Constants#SMT_DEFAULT_OS_KEY}
|
||||||
* {@value Constants#SMT_DEFAULT_OS_KEY} with {@link #DEFAULT_VENDOR} and
|
* with {@link #DEFAULT_VENDOR} and {@link #DEFAULT_VERSION} and random
|
||||||
* {@link #DEFAULT_VERSION} and random generated
|
* generated {@link Target#getDescription()} in the repository.
|
||||||
* {@link Target#getDescription()} in the repository.
|
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* @return persisted {@link SoftwareModule}.
|
* @return persisted {@link SoftwareModule}.
|
||||||
*/
|
*/
|
||||||
@@ -573,15 +544,12 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link SoftwareModule} of type
|
* Creates {@link SoftwareModule} of type {@value Constants#SMT_DEFAULT_OS_KEY}
|
||||||
* {@value Constants#SMT_DEFAULT_OS_KEY} with {@link #DEFAULT_VENDOR} and
|
* with {@link #DEFAULT_VENDOR} and {@link #DEFAULT_VERSION} and random
|
||||||
* {@link #DEFAULT_VERSION} and random generated
|
* generated {@link Target#getDescription()} in the repository.
|
||||||
* {@link Target#getDescription()} in the repository.
|
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix
|
||||||
* added to name and version
|
* added to name and version
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return persisted {@link SoftwareModule}.
|
* @return persisted {@link SoftwareModule}.
|
||||||
*/
|
*/
|
||||||
public SoftwareModule createSoftwareModuleOs(final String prefix) {
|
public SoftwareModule createSoftwareModuleOs(final String prefix) {
|
||||||
@@ -590,14 +558,13 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link SoftwareModule} with {@link #DEFAULT_VENDOR} and
|
* Creates {@link SoftwareModule} with {@link #DEFAULT_VENDOR} and
|
||||||
* {@link #DEFAULT_VERSION} and random generated
|
* {@link #DEFAULT_VERSION} and random generated {@link Target#getDescription()}
|
||||||
* {@link Target#getDescription()} in the repository.
|
* in the repository.
|
||||||
*
|
*
|
||||||
* @param typeKey
|
* @param typeKey
|
||||||
* of the {@link SoftwareModuleType}
|
* of the {@link SoftwareModuleType}
|
||||||
* @param prefix
|
* @param prefix
|
||||||
* added to name and version
|
* added to name and version
|
||||||
*
|
|
||||||
* @return persisted {@link SoftwareModule}.
|
* @return persisted {@link SoftwareModule}.
|
||||||
*/
|
*/
|
||||||
public SoftwareModule createSoftwareModule(final String typeKey, final String prefix) {
|
public SoftwareModule createSoftwareModule(final String typeKey, final String prefix) {
|
||||||
@@ -619,27 +586,42 @@ public class TestdataFactory {
|
|||||||
* @return persisted {@link Target}
|
* @return persisted {@link Target}
|
||||||
*/
|
*/
|
||||||
public Target createTarget(final String controllerId) {
|
public Target createTarget(final String controllerId) {
|
||||||
final Target target = targetManagement.create(entityFactory.target().create().controllerId(controllerId));
|
return createTarget(controllerId, controllerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param controllerId
|
||||||
|
* of the target
|
||||||
|
* @param targetName
|
||||||
|
* name of the target
|
||||||
|
* @return persisted {@link Target}
|
||||||
|
*/
|
||||||
|
public Target createTarget(final String controllerId, final String targetName) {
|
||||||
|
final Target target = targetManagement
|
||||||
|
.create(entityFactory.target().create().controllerId(controllerId).name(targetName));
|
||||||
|
assertTargetProperlyCreated(target);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertTargetProperlyCreated(Target target) {
|
||||||
assertThat(target.getCreatedBy()).isNotNull();
|
assertThat(target.getCreatedBy()).isNotNull();
|
||||||
assertThat(target.getCreatedAt()).isNotNull();
|
assertThat(target.getCreatedAt()).isNotNull();
|
||||||
assertThat(target.getLastModifiedBy()).isNotNull();
|
assertThat(target.getLastModifiedBy()).isNotNull();
|
||||||
assertThat(target.getLastModifiedAt()).isNotNull();
|
assertThat(target.getLastModifiedAt()).isNotNull();
|
||||||
|
|
||||||
assertThat(target.getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
|
assertThat(target.getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||||
return target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link DistributionSet}s in repository including three
|
* Creates {@link DistributionSet}s in repository including three
|
||||||
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
|
||||||
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} followed by an
|
* {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} followed by an iterative
|
||||||
* iterative number and {@link DistributionSet#isRequiredMigrationStep()}
|
* number and {@link DistributionSet#isRequiredMigrationStep()}
|
||||||
* <code>false</code>.
|
* <code>false</code>.
|
||||||
*
|
*
|
||||||
* In addition it updates the created {@link DistributionSet}s and
|
* In addition it updates the created {@link DistributionSet}s and
|
||||||
* {@link SoftwareModule}s to ensure that
|
* {@link SoftwareModule}s to ensure that {@link BaseEntity#getLastModifiedAt()}
|
||||||
* {@link BaseEntity#getLastModifiedAt()} and
|
* and {@link BaseEntity#getLastModifiedBy()} is filled.
|
||||||
* {@link BaseEntity#getLastModifiedBy()} is filled.
|
|
||||||
*
|
*
|
||||||
* @return persisted {@link DistributionSet}.
|
* @return persisted {@link DistributionSet}.
|
||||||
*/
|
*/
|
||||||
@@ -657,8 +639,8 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {@link DistributionSetType} with key {@link #DS_TYPE_DEFAULT} and
|
* @return {@link DistributionSetType} with key {@link #DS_TYPE_DEFAULT} and
|
||||||
* {@link SoftwareModuleType}s {@link #SM_TYPE_OS},
|
* {@link SoftwareModuleType}s {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
|
||||||
* {@link #SM_TYPE_RT} , {@link #SM_TYPE_APP}.
|
* , {@link #SM_TYPE_APP}.
|
||||||
*/
|
*/
|
||||||
public DistributionSetType findOrCreateDefaultTestDsType() {
|
public DistributionSetType findOrCreateDefaultTestDsType() {
|
||||||
final List<SoftwareModuleType> mand = new ArrayList<>();
|
final List<SoftwareModuleType> mand = new ArrayList<>();
|
||||||
@@ -679,7 +661,6 @@ public class TestdataFactory {
|
|||||||
* {@link DistributionSetType#getKey()}
|
* {@link DistributionSetType#getKey()}
|
||||||
* @param dsTypeName
|
* @param dsTypeName
|
||||||
* {@link DistributionSetType#getName()}
|
* {@link DistributionSetType#getName()}
|
||||||
*
|
|
||||||
* @return persisted {@link DistributionSetType}
|
* @return persisted {@link DistributionSetType}
|
||||||
*/
|
*/
|
||||||
public DistributionSetType findOrCreateDistributionSetType(final String dsTypeKey, final String dsTypeName) {
|
public DistributionSetType findOrCreateDistributionSetType(final String dsTypeKey, final String dsTypeName) {
|
||||||
@@ -700,7 +681,6 @@ public class TestdataFactory {
|
|||||||
* {@link DistributionSetType#getMandatoryModuleTypes()}
|
* {@link DistributionSetType#getMandatoryModuleTypes()}
|
||||||
* @param optional
|
* @param optional
|
||||||
* {@link DistributionSetType#getOptionalModuleTypes()}
|
* {@link DistributionSetType#getOptionalModuleTypes()}
|
||||||
*
|
|
||||||
* @return persisted {@link DistributionSetType}
|
* @return persisted {@link DistributionSetType}
|
||||||
*/
|
*/
|
||||||
public DistributionSetType findOrCreateDistributionSetType(final String dsTypeKey, final String dsTypeName,
|
public DistributionSetType findOrCreateDistributionSetType(final String dsTypeKey, final String dsTypeName,
|
||||||
@@ -714,12 +694,11 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds {@link SoftwareModuleType} in repository with given
|
* Finds {@link SoftwareModuleType} in repository with given
|
||||||
* {@link SoftwareModuleType#getKey()} or creates if it does not exist yet
|
* {@link SoftwareModuleType#getKey()} or creates if it does not exist yet with
|
||||||
* with {@link SoftwareModuleType#getMaxAssignments()} = 1.
|
* {@link SoftwareModuleType#getMaxAssignments()} = 1.
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* {@link SoftwareModuleType#getKey()}
|
* {@link SoftwareModuleType#getKey()}
|
||||||
*
|
|
||||||
* @return persisted {@link SoftwareModuleType}
|
* @return persisted {@link SoftwareModuleType}
|
||||||
*/
|
*/
|
||||||
public SoftwareModuleType findOrCreateSoftwareModuleType(final String key) {
|
public SoftwareModuleType findOrCreateSoftwareModuleType(final String key) {
|
||||||
@@ -734,7 +713,6 @@ public class TestdataFactory {
|
|||||||
* {@link SoftwareModuleType#getKey()}
|
* {@link SoftwareModuleType#getKey()}
|
||||||
* @param maxAssignments
|
* @param maxAssignments
|
||||||
* {@link SoftwareModuleType#getMaxAssignments()}
|
* {@link SoftwareModuleType#getMaxAssignments()}
|
||||||
*
|
|
||||||
* @return persisted {@link SoftwareModuleType}
|
* @return persisted {@link SoftwareModuleType}
|
||||||
*/
|
*/
|
||||||
public SoftwareModuleType findOrCreateSoftwareModuleType(final String key, final int maxAssignments) {
|
public SoftwareModuleType findOrCreateSoftwareModuleType(final String key, final int maxAssignments) {
|
||||||
@@ -754,7 +732,6 @@ public class TestdataFactory {
|
|||||||
* {@link DistributionSet#getType()}
|
* {@link DistributionSet#getType()}
|
||||||
* @param modules
|
* @param modules
|
||||||
* {@link DistributionSet#getModules()}
|
* {@link DistributionSet#getModules()}
|
||||||
*
|
|
||||||
* @return the created {@link DistributionSet}
|
* @return the created {@link DistributionSet}
|
||||||
*/
|
*/
|
||||||
public DistributionSet createDistributionSet(final String name, final String version,
|
public DistributionSet createDistributionSet(final String name, final String version,
|
||||||
@@ -777,7 +754,6 @@ public class TestdataFactory {
|
|||||||
* {@link DistributionSet#getModules()}
|
* {@link DistributionSet#getModules()}
|
||||||
* @param requiredMigrationStep
|
* @param requiredMigrationStep
|
||||||
* {@link DistributionSet#isRequiredMigrationStep()}
|
* {@link DistributionSet#isRequiredMigrationStep()}
|
||||||
*
|
|
||||||
* @return the created {@link DistributionSet}
|
* @return the created {@link DistributionSet}
|
||||||
*/
|
*/
|
||||||
public DistributionSet generateDistributionSet(final String name, final String version,
|
public DistributionSet generateDistributionSet(final String name, final String version,
|
||||||
@@ -799,7 +775,6 @@ public class TestdataFactory {
|
|||||||
* {@link DistributionSet#getType()}
|
* {@link DistributionSet#getType()}
|
||||||
* @param modules
|
* @param modules
|
||||||
* {@link DistributionSet#getModules()}
|
* {@link DistributionSet#getModules()}
|
||||||
*
|
|
||||||
* @return the created {@link DistributionSet}
|
* @return the created {@link DistributionSet}
|
||||||
*/
|
*/
|
||||||
public DistributionSet generateDistributionSet(final String name, final String version,
|
public DistributionSet generateDistributionSet(final String name, final String version,
|
||||||
@@ -812,7 +787,6 @@ public class TestdataFactory {
|
|||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
* {@link DistributionSet#getName()}
|
* {@link DistributionSet#getName()}
|
||||||
*
|
|
||||||
* @return the generated {@link DistributionSet}
|
* @return the generated {@link DistributionSet}
|
||||||
*/
|
*/
|
||||||
public DistributionSet generateDistributionSet(final String name) {
|
public DistributionSet generateDistributionSet(final String name) {
|
||||||
@@ -821,13 +795,11 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link Target}s in repository and with
|
* Creates {@link Target}s in repository and with {@link #DEFAULT_CONTROLLER_ID}
|
||||||
* {@link #DEFAULT_CONTROLLER_ID} as prefix for
|
* as prefix for {@link Target#getControllerId()}.
|
||||||
* {@link Target#getControllerId()}.
|
|
||||||
*
|
*
|
||||||
* @param number
|
* @param number
|
||||||
* of {@link Target}s to create
|
* of {@link Target}s to create
|
||||||
*
|
|
||||||
* @return {@link List} of {@link Target} entities
|
* @return {@link List} of {@link Target} entities
|
||||||
*/
|
*/
|
||||||
public List<Target> createTargets(final int number) {
|
public List<Target> createTargets(final int number) {
|
||||||
@@ -863,8 +835,7 @@ public class TestdataFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds {@link Target} objects with given prefix for
|
* Builds {@link Target} objects with given prefix for
|
||||||
* {@link Target#getControllerId()} followed by a number suffix starting
|
* {@link Target#getControllerId()} followed by a number suffix starting with 0.
|
||||||
* with 0.
|
|
||||||
*
|
*
|
||||||
* @param numberOfTargets
|
* @param numberOfTargets
|
||||||
* of {@link Target}s to generate
|
* of {@link Target}s to generate
|
||||||
@@ -958,7 +929,6 @@ public class TestdataFactory {
|
|||||||
*
|
*
|
||||||
* @param number
|
* @param number
|
||||||
* of {@link DistributionSetTag}s
|
* of {@link DistributionSetTag}s
|
||||||
*
|
|
||||||
* @return the persisted {@link DistributionSetTag}s
|
* @return the persisted {@link DistributionSetTag}s
|
||||||
*/
|
*/
|
||||||
public List<DistributionSetTag> createDistributionSetTags(final int number) {
|
public List<DistributionSetTag> createDistributionSetTags(final int number) {
|
||||||
@@ -980,8 +950,7 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append {@link ActionStatus} to all {@link Action}s of given
|
* Append {@link ActionStatus} to all {@link Action}s of given {@link Target}s.
|
||||||
* {@link Target}s.
|
|
||||||
*
|
*
|
||||||
* @param targets
|
* @param targets
|
||||||
* to add {@link ActionStatus}
|
* to add {@link ActionStatus}
|
||||||
@@ -989,7 +958,6 @@ public class TestdataFactory {
|
|||||||
* to add
|
* to add
|
||||||
* @param message
|
* @param message
|
||||||
* to add
|
* to add
|
||||||
*
|
|
||||||
* @return updated {@link Action}.
|
* @return updated {@link Action}.
|
||||||
*/
|
*/
|
||||||
public List<Action> sendUpdateActionStatusToTargets(final Collection<Target> targets, final Status status,
|
public List<Action> sendUpdateActionStatusToTargets(final Collection<Target> targets, final Status status,
|
||||||
@@ -998,8 +966,7 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append {@link ActionStatus} to all {@link Action}s of given
|
* Append {@link ActionStatus} to all {@link Action}s of given {@link Target}s.
|
||||||
* {@link Target}s.
|
|
||||||
*
|
*
|
||||||
* @param targets
|
* @param targets
|
||||||
* to add {@link ActionStatus}
|
* to add {@link ActionStatus}
|
||||||
@@ -1007,7 +974,6 @@ public class TestdataFactory {
|
|||||||
* to add
|
* to add
|
||||||
* @param msgs
|
* @param msgs
|
||||||
* to add
|
* to add
|
||||||
*
|
|
||||||
* @return updated {@link Action}.
|
* @return updated {@link Action}.
|
||||||
*/
|
*/
|
||||||
public List<Action> sendUpdateActionStatusToTargets(final Collection<Target> targets, final Status status,
|
public List<Action> sendUpdateActionStatusToTargets(final Collection<Target> targets, final Status status,
|
||||||
@@ -1045,7 +1011,8 @@ public class TestdataFactory {
|
|||||||
public Rollout createRolloutByVariables(final String rolloutName, final String rolloutDescription,
|
public Rollout createRolloutByVariables(final String rolloutName, final String rolloutDescription,
|
||||||
final int groupSize, final String filterQuery, final DistributionSet distributionSet,
|
final int groupSize, final String filterQuery, final DistributionSet distributionSet,
|
||||||
final String successCondition, final String errorCondition) {
|
final String successCondition, final String errorCondition) {
|
||||||
return createRolloutByVariables(rolloutName, rolloutDescription, groupSize, filterQuery, distributionSet, successCondition, errorCondition, Action.ActionType.FORCED);
|
return createRolloutByVariables(rolloutName, rolloutDescription, groupSize, filterQuery, distributionSet,
|
||||||
|
successCondition, errorCondition, Action.ActionType.FORCED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1077,9 +1044,10 @@ public class TestdataFactory {
|
|||||||
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition)
|
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition)
|
||||||
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
|
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
|
||||||
|
|
||||||
final Rollout rollout = rolloutManagement.create(entityFactory.rollout().create().name(rolloutName)
|
final Rollout rollout = rolloutManagement.create(
|
||||||
.description(rolloutDescription).targetFilterQuery(filterQuery).set(distributionSet)
|
entityFactory.rollout().create().name(rolloutName).description(rolloutDescription)
|
||||||
.actionType(actionType), groupSize, conditions);
|
.targetFilterQuery(filterQuery).set(distributionSet).actionType(actionType),
|
||||||
|
groupSize, conditions);
|
||||||
|
|
||||||
// Run here, because Scheduler is disabled during tests
|
// Run here, because Scheduler is disabled during tests
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
@@ -1092,8 +1060,8 @@ public class TestdataFactory {
|
|||||||
* {@link Target}s.
|
* {@link Target}s.
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix
|
||||||
* for rollouts name, description,
|
* for rollouts name, description, {@link Target#getControllerId()}
|
||||||
* {@link Target#getControllerId()} filter
|
* filter
|
||||||
* @return created {@link Rollout}
|
* @return created {@link Rollout}
|
||||||
*/
|
*/
|
||||||
public Rollout createRollout(final String prefix) {
|
public Rollout createRollout(final String prefix) {
|
||||||
@@ -1103,12 +1071,12 @@ public class TestdataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the soft deleted {@link Rollout} with a new
|
* Create the soft deleted {@link Rollout} with a new {@link DistributionSet}
|
||||||
* {@link DistributionSet} and {@link Target}s.
|
* and {@link Target}s.
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix
|
||||||
* for rollouts name, description,
|
* for rollouts name, description, {@link Target#getControllerId()}
|
||||||
* {@link Target#getControllerId()} filter
|
* filter
|
||||||
* @return created {@link Rollout}
|
* @return created {@link Rollout}
|
||||||
*/
|
*/
|
||||||
public Rollout createSoftDeletedRollout(final String prefix) {
|
public Rollout createSoftDeletedRollout(final String prefix) {
|
||||||
|
|||||||
Reference in New Issue
Block a user