Test and build performance improvements (#552)
* Small build perf improvements. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Remove dead code. Stabilize test. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Further optimizations Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Upgrade mariadb driver. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Raise timeouts for more robustness on slower build environments. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Move webappcontext into rest tests. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Raised timeout. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Remove test dependency on target to groups distribution order. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Code reuse. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Context available to tests. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Typos fixed. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix PollEvent send. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix typos. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Test log readability and removed unused method from CM. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Remove empty payload. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Stabilize tests. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Raised timeout. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fixed fire directory change during one test class run. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
1
hawkbit-dmf/hawkbit-dmf-amqp/.gitignore
vendored
Normal file
1
hawkbit-dmf/hawkbit-dmf-amqp/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/artifactrepo/
|
||||
@@ -37,6 +37,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
||||
@Features("Component Tests - Device Management Federation API")
|
||||
@Stories("Amqp Message Dispatcher Service")
|
||||
public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceIntegrationTest {
|
||||
private static final String TARGET_PREFIX = "Dmf_disp_";
|
||||
|
||||
@Test
|
||||
@Description("Verify that a distribution assignment send a download and install message.")
|
||||
@@ -47,11 +48,12 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
|
||||
public void sendDownloadAndInstallStatus() {
|
||||
registerTargetAndAssignDistributionSet();
|
||||
final String controllerId = TARGET_PREFIX + "sendDownloadAndInstallStatus";
|
||||
registerTargetAndAssignDistributionSet(controllerId);
|
||||
|
||||
createAndSendTarget(TENANT_EXIST);
|
||||
waitUntilTargetStatusIsPending();
|
||||
assertDownloadAndInstallMessage(getDistributionSet().getModules());
|
||||
createAndSendTarget(controllerId, TENANT_EXIST);
|
||||
waitUntilTargetStatusIsPending(controllerId);
|
||||
assertDownloadAndInstallMessage(getDistributionSet().getModules(), controllerId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -64,16 +66,18 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 3) })
|
||||
public void assignDistributionSetMultipleTimes() {
|
||||
final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet();
|
||||
final String controllerId = TARGET_PREFIX + "assignDistributionSetMultipleTimes";
|
||||
|
||||
final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet(controllerId);
|
||||
|
||||
final DistributionSet distributionSet2 = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
||||
registerTargetAndAssignDistributionSet(distributionSet2.getId(), TargetUpdateStatus.PENDING,
|
||||
getDistributionSet().getModules());
|
||||
assertCancelActionMessage(assignmentResult.getActions().get(0));
|
||||
getDistributionSet().getModules(), controllerId);
|
||||
assertCancelActionMessage(assignmentResult.getActions().get(0), controllerId);
|
||||
|
||||
createAndSendTarget(TENANT_EXIST);
|
||||
waitUntilTargetStatusIsPending();
|
||||
assertCancelActionMessage(assignmentResult.getActions().get(0));
|
||||
createAndSendTarget(controllerId, TENANT_EXIST);
|
||||
waitUntilTargetStatusIsPending(controllerId);
|
||||
assertCancelActionMessage(assignmentResult.getActions().get(0), controllerId);
|
||||
|
||||
}
|
||||
|
||||
@@ -87,11 +91,13 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
|
||||
public void sendCancelStatus() {
|
||||
final Long actionId = registerTargetAndCancelActionId();
|
||||
final String controllerId = TARGET_PREFIX + "sendCancelStatus";
|
||||
|
||||
createAndSendTarget(TENANT_EXIST);
|
||||
waitUntilTargetStatusIsPending();
|
||||
assertCancelActionMessage(actionId);
|
||||
final Long actionId = registerTargetAndCancelActionId(controllerId);
|
||||
|
||||
createAndSendTarget(controllerId, TENANT_EXIST);
|
||||
waitUntilTargetStatusIsPending(controllerId);
|
||||
assertCancelActionMessage(actionId, controllerId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -99,16 +105,16 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1), @Expect(type = TargetDeletedEvent.class, count = 1) })
|
||||
public void sendDeleteMessage() {
|
||||
final String controllerId = TARGET_PREFIX + "sendDeleteMessage";
|
||||
|
||||
registerAndAssertTargetWithExistingTenant(REGISTER_TARGET, 1);
|
||||
targetManagement.deleteTarget(REGISTER_TARGET);
|
||||
assertDeleteMessage(REGISTER_TARGET);
|
||||
registerAndAssertTargetWithExistingTenant(controllerId, 1);
|
||||
targetManagement.deleteTarget(controllerId);
|
||||
assertDeleteMessage(controllerId);
|
||||
}
|
||||
|
||||
private void waitUntilTargetStatusIsPending() {
|
||||
private void waitUntilTargetStatusIsPending(final String controllerId) {
|
||||
waitUntil(() -> {
|
||||
final Optional<Target> findTargetByControllerID = targetManagement
|
||||
.findTargetByControllerID(REGISTER_TARGET);
|
||||
final Optional<Target> findTargetByControllerID = targetManagement.findTargetByControllerID(controllerId);
|
||||
return findTargetByControllerID.isPresent()
|
||||
&& TargetUpdateStatus.PENDING.equals(findTargetByControllerID.get().getUpdateStatus());
|
||||
});
|
||||
@@ -119,9 +125,4 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
|
||||
return securityRule.runAsPrivileged(callable);
|
||||
});
|
||||
}
|
||||
|
||||
private void createAndSendTarget(final String tenant) {
|
||||
createAndSendTarget(REGISTER_TARGET, tenant);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedE
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||
@@ -54,6 +54,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
||||
@Stories("Amqp Message Handler Service")
|
||||
public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegrationTest {
|
||||
private static final String CORRELATION_ID = UUID.randomUUID().toString();
|
||||
private static final String TARGET_PREFIX = "Dmf_hand_";
|
||||
|
||||
@Autowired
|
||||
private AmqpProperties amqpProperties;
|
||||
@@ -63,12 +64,13 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 2),
|
||||
@Expect(type = TargetPollEvent.class, count = 3) })
|
||||
public void registerTargets() {
|
||||
registerAndAssertTargetWithExistingTenant(REGISTER_TARGET, 1);
|
||||
final String controllerId = TARGET_PREFIX + "registerTargets";
|
||||
registerAndAssertTargetWithExistingTenant(controllerId, 1);
|
||||
|
||||
final String target2 = "Target2";
|
||||
registerAndAssertTargetWithExistingTenant(target2, 2);
|
||||
final Long pollingTimeTarget2 = controllerManagement.findByControllerId(target2).get().getLastTargetQuery();
|
||||
registerSameTargetAndAssertBasedOnLastPolling(target2, 2, TargetUpdateStatus.REGISTERED, pollingTimeTarget2);
|
||||
|
||||
registerSameTargetAndAssertBasedOnVersion(target2, 2, TargetUpdateStatus.REGISTERED);
|
||||
Mockito.verifyZeroInteractions(getDeadletterListener());
|
||||
}
|
||||
|
||||
@@ -106,7 +108,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Description("Tests not allowed content-type in message. This message should forwarded to the deadletter queue")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
||||
public void wrongContentType() {
|
||||
final Message createTargetMessage = createTargetMessage(REGISTER_TARGET, TENANT_EXIST);
|
||||
final String controllerId = TARGET_PREFIX + "wrongContentType";
|
||||
final Message createTargetMessage = createTargetMessage(controllerId, TENANT_EXIST);
|
||||
createTargetMessage.getMessageProperties().setContentType("WrongContentType");
|
||||
getDmfClient().send(createTargetMessage);
|
||||
|
||||
@@ -118,7 +121,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Description("Tests null reply to property in message header. This message should forwarded to the deadletter queue")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
||||
public void missingReplyToProperty() {
|
||||
final Message createTargetMessage = createTargetMessage(REGISTER_TARGET, TENANT_EXIST);
|
||||
final String controllerId = TARGET_PREFIX + "missingReplyToProperty";
|
||||
final Message createTargetMessage = createTargetMessage(controllerId, TENANT_EXIST);
|
||||
createTargetMessage.getMessageProperties().setReplyTo(null);
|
||||
getDmfClient().send(createTargetMessage);
|
||||
|
||||
@@ -130,7 +134,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Description("Tests missing reply to property in message header. This message should forwarded to the deadletter queue")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
||||
public void emptyReplyToProperty() {
|
||||
final Message createTargetMessage = createTargetMessage(REGISTER_TARGET, TENANT_EXIST);
|
||||
final String controllerId = TARGET_PREFIX + "emptyReplyToProperty";
|
||||
final Message createTargetMessage = createTargetMessage(controllerId, TENANT_EXIST);
|
||||
createTargetMessage.getMessageProperties().setReplyTo("");
|
||||
getDmfClient().send(createTargetMessage);
|
||||
|
||||
@@ -165,7 +170,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Description("Tests missing tenant message header. This message should forwarded to the deadletter queue")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
||||
public void missingTenantHeader() {
|
||||
final Message createTargetMessage = createTargetMessage(REGISTER_TARGET, TENANT_EXIST);
|
||||
final String controllerId = TARGET_PREFIX + "missingTenantHeader";
|
||||
final Message createTargetMessage = createTargetMessage(controllerId, TENANT_EXIST);
|
||||
createTargetMessage.getMessageProperties().getHeaders().remove(MessageHeaderKey.TENANT);
|
||||
getDmfClient().send(createTargetMessage);
|
||||
|
||||
@@ -177,7 +183,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Description("Tests null tenant message header. This message should forwarded to the deadletter queue")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
||||
public void nullTenantHeader() {
|
||||
final Message createTargetMessage = createTargetMessage(REGISTER_TARGET, null);
|
||||
final String controllerId = TARGET_PREFIX + "nullTenantHeader";
|
||||
final Message createTargetMessage = createTargetMessage(controllerId, null);
|
||||
getDmfClient().send(createTargetMessage);
|
||||
|
||||
verifyOneDeadLetterMessage();
|
||||
@@ -188,7 +195,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Description("Tests empty tenant message header. This message should forwarded to the deadletter queue")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
||||
public void emptyTenantHeader() {
|
||||
final Message createTargetMessage = createTargetMessage(REGISTER_TARGET, "");
|
||||
final String controllerId = TARGET_PREFIX + "emptyTenantHeader";
|
||||
final Message createTargetMessage = createTargetMessage(controllerId, "");
|
||||
getDmfClient().send(createTargetMessage);
|
||||
|
||||
verifyOneDeadLetterMessage();
|
||||
@@ -199,7 +207,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Description("Tests tenant not exist. This message should forwarded to the deadletter queue")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
||||
public void tenantNotExist() {
|
||||
final Message createTargetMessage = createTargetMessage(REGISTER_TARGET, "TenantNotExist");
|
||||
final String controllerId = TARGET_PREFIX + "tenantNotExist";
|
||||
final Message createTargetMessage = createTargetMessage(controllerId, "TenantNotExist");
|
||||
getDmfClient().send(createTargetMessage);
|
||||
|
||||
verifyOneDeadLetterMessage();
|
||||
@@ -346,7 +355,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void finishActionStatus() {
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.FINISHED, Status.FINISHED);
|
||||
final String controllerId = TARGET_PREFIX + "finishActionStatus";
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.FINISHED, Status.FINISHED, controllerId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -358,7 +368,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void runningActionStatus() {
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.RUNNING, Status.RUNNING);
|
||||
final String controllerId = TARGET_PREFIX + "runningActionStatus";
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.RUNNING, Status.RUNNING, controllerId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -370,7 +381,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void downloadActionStatus() {
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.DOWNLOAD, Status.DOWNLOAD);
|
||||
final String controllerId = TARGET_PREFIX + "downloadActionStatus";
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.DOWNLOAD, Status.DOWNLOAD, controllerId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -382,7 +394,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void errorActionStatus() {
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.ERROR, Status.ERROR);
|
||||
final String controllerId = TARGET_PREFIX + "errorActionStatus";
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.ERROR, Status.ERROR, controllerId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -394,7 +407,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void warningActionStatus() {
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.WARNING, Status.WARNING);
|
||||
final String controllerId = TARGET_PREFIX + "warningActionStatus";
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.WARNING, Status.WARNING, controllerId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -406,7 +420,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void retrievedActionStatus() {
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.RETRIEVED, Status.RETRIEVED);
|
||||
final String controllerId = TARGET_PREFIX + "retrievedActionStatus";
|
||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.RETRIEVED, Status.RETRIEVED, controllerId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -418,7 +433,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void cancelNotAllowActionStatus() {
|
||||
registerTargetAndSendActionStatus(DmfActionStatus.CANCELED);
|
||||
final String controllerId = TARGET_PREFIX + "cancelNotAllowActionStatus";
|
||||
registerTargetAndSendActionStatus(DmfActionStatus.CANCELED, controllerId);
|
||||
verifyOneDeadLetterMessage();
|
||||
}
|
||||
|
||||
@@ -431,17 +447,18 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
|
||||
public void receiveDownLoadAndInstallMessageAfterAssignment() {
|
||||
final String controllerId = TARGET_PREFIX + "receiveDownLoadAndInstallMessageAfterAssignment";
|
||||
|
||||
// setup
|
||||
controllerManagement.findOrRegisterTargetIfItDoesNotexist(REGISTER_TARGET, TEST_URI);
|
||||
controllerManagement.findOrRegisterTargetIfItDoesNotexist(controllerId, TEST_URI);
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
||||
assignDistributionSet(distributionSet.getId(), REGISTER_TARGET);
|
||||
assignDistributionSet(distributionSet.getId(), controllerId);
|
||||
|
||||
// test
|
||||
registerAndAssertTargetWithExistingTenant(REGISTER_TARGET, 1, TargetUpdateStatus.PENDING, "bumlux");
|
||||
registerSameTargetAndAssertBasedOnVersion(controllerId, 1, TargetUpdateStatus.PENDING);
|
||||
|
||||
// verify
|
||||
assertDownloadAndInstallMessage(distributionSet.getModules());
|
||||
assertDownloadAndInstallMessage(distributionSet.getModules(), controllerId);
|
||||
Mockito.verifyZeroInteractions(getDeadletterListener());
|
||||
}
|
||||
|
||||
@@ -456,20 +473,20 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 2) })
|
||||
public void receiveCancelUpdateMessageAfterAssignmentWasCanceled() {
|
||||
final String controllerId = TARGET_PREFIX + "receiveCancelUpdateMessageAfterAssignmentWasCanceled";
|
||||
|
||||
// Setup
|
||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(REGISTER_TARGET, TEST_URI);
|
||||
controllerManagement.findOrRegisterTargetIfItDoesNotexist(controllerId, TEST_URI);
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
||||
final DistributionSetAssignmentResult distributionSetAssignmentResult = assignDistributionSet(
|
||||
distributionSet.getId(), REGISTER_TARGET);
|
||||
distributionSet.getId(), controllerId);
|
||||
deploymentManagement.cancelAction(distributionSetAssignmentResult.getActions().get(0));
|
||||
|
||||
// test
|
||||
registerSameTargetAndAssertBasedOnLastPolling(REGISTER_TARGET, 1, TargetUpdateStatus.PENDING,
|
||||
target.getLastTargetQuery());
|
||||
registerSameTargetAndAssertBasedOnVersion(controllerId, 1, TargetUpdateStatus.PENDING);
|
||||
|
||||
// verify
|
||||
assertCancelActionMessage(distributionSetAssignmentResult.getActions().get(0));
|
||||
assertCancelActionMessage(distributionSetAssignmentResult.getActions().get(0), controllerId);
|
||||
Mockito.verifyZeroInteractions(getDeadletterListener());
|
||||
}
|
||||
|
||||
@@ -483,7 +500,9 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void actionNotExists() {
|
||||
final Long actionId = registerTargetAndCancelActionId();
|
||||
final String controllerId = TARGET_PREFIX + "actionNotExists";
|
||||
|
||||
final Long actionId = registerTargetAndCancelActionId(controllerId);
|
||||
final Long actionNotExist = actionId + 1;
|
||||
|
||||
sendActionUpdateStatus(new DmfActionUpdateStatus(actionNotExist, DmfActionStatus.CANCELED));
|
||||
@@ -499,7 +518,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void canceledRejectedNotAllowActionStatus() {
|
||||
registerTargetAndSendActionStatus(DmfActionStatus.CANCEL_REJECTED);
|
||||
final String controllerId = TARGET_PREFIX + "canceledRejectedNotAllowActionStatus";
|
||||
registerTargetAndSendActionStatus(DmfActionStatus.CANCEL_REJECTED, controllerId);
|
||||
verifyOneDeadLetterMessage();
|
||||
}
|
||||
|
||||
@@ -513,7 +533,9 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void canceledRejectedActionStatus() {
|
||||
final Long actionId = registerTargetAndCancelActionId();
|
||||
final String controllerId = TARGET_PREFIX + "canceledRejectedActionStatus";
|
||||
|
||||
final Long actionId = registerTargetAndCancelActionId(controllerId);
|
||||
|
||||
sendActionUpdateStatus(new DmfActionUpdateStatus(actionId, DmfActionStatus.CANCEL_REJECTED));
|
||||
assertAction(actionId, 1, Status.RUNNING, Status.CANCELING, Status.CANCEL_REJECTED);
|
||||
@@ -524,19 +546,19 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void updateAttributes() {
|
||||
final String controllerId = TARGET_PREFIX + "updateAttributes";
|
||||
|
||||
// setup
|
||||
final String target = "ControllerAttributeTestTarget";
|
||||
registerAndAssertTargetWithExistingTenant(target, 1);
|
||||
registerAndAssertTargetWithExistingTenant(controllerId, 1);
|
||||
final DmfAttributeUpdate controllerAttribute = new DmfAttributeUpdate();
|
||||
controllerAttribute.getAttributes().put("test1", "testA");
|
||||
controllerAttribute.getAttributes().put("test2", "testB");
|
||||
|
||||
// test
|
||||
sendUpdateAttributeMessage(target, TENANT_EXIST, controllerAttribute);
|
||||
sendUpdateAttributeMessage(controllerId, TENANT_EXIST, controllerAttribute);
|
||||
|
||||
// validate
|
||||
assertUpdateAttributes(target, controllerAttribute.getAttributes());
|
||||
assertUpdateAttributes(controllerId, controllerAttribute.getAttributes());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -544,10 +566,10 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 0), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void updateAttributesWithNoThingId() {
|
||||
final String controllerId = TARGET_PREFIX + "updateAttributesWithNoThingId";
|
||||
|
||||
// setup
|
||||
final String target = "ControllerAttributeTestTarget";
|
||||
registerAndAssertTargetWithExistingTenant(target, 1);
|
||||
registerAndAssertTargetWithExistingTenant(controllerId, 1);
|
||||
final DmfAttributeUpdate controllerAttribute = new DmfAttributeUpdate();
|
||||
controllerAttribute.getAttributes().put("test1", "testA");
|
||||
controllerAttribute.getAttributes().put("test2", "testB");
|
||||
@@ -561,7 +583,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
// verify
|
||||
verifyOneDeadLetterMessage();
|
||||
final DmfAttributeUpdate controllerAttributeEmpty = new DmfAttributeUpdate();
|
||||
assertUpdateAttributes(target, controllerAttributeEmpty.getAttributes());
|
||||
assertUpdateAttributes(controllerId, controllerAttributeEmpty.getAttributes());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -586,8 +608,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
verifyOneDeadLetterMessage();
|
||||
}
|
||||
|
||||
private Long registerTargetAndSendActionStatus(final DmfActionStatus sendActionStatus) {
|
||||
final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet();
|
||||
private Long registerTargetAndSendActionStatus(final DmfActionStatus sendActionStatus, final String controllerId) {
|
||||
final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet(controllerId);
|
||||
final Long actionId = assignmentResult.getActions().get(0);
|
||||
sendActionUpdateStatus(new DmfActionUpdateStatus(actionId, sendActionStatus));
|
||||
return actionId;
|
||||
@@ -599,8 +621,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
}
|
||||
|
||||
private void registerTargetAndSendAndAssertUpdateActionStatus(final DmfActionStatus sendActionStatus,
|
||||
final Status expectedActionStatus) {
|
||||
final Long actionId = registerTargetAndSendActionStatus(sendActionStatus);
|
||||
final Status expectedActionStatus, final String controllerId) {
|
||||
final Long actionId = registerTargetAndSendActionStatus(sendActionStatus, controllerId);
|
||||
assertAction(actionId, 1, Status.RUNNING, expectedActionStatus);
|
||||
}
|
||||
|
||||
@@ -608,7 +630,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
createConditionFactory().await().until(() -> {
|
||||
try {
|
||||
securityRule.runAsPrivileged(() -> {
|
||||
final List<org.eclipse.hawkbit.repository.model.ActionStatus> actionStatusList = deploymentManagement
|
||||
final List<ActionStatus> actionStatusList = deploymentManagement
|
||||
.findActionStatusByAction(PAGE, actionId).getContent();
|
||||
|
||||
// Check correlation ID
|
||||
@@ -623,7 +645,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
assertThat(messagesFromServer).hasSize(messages)
|
||||
.allMatch(message -> message.endsWith(CORRELATION_ID));
|
||||
|
||||
final List<Status> status = actionStatusList.stream().map(actionStatus -> actionStatus.getStatus())
|
||||
final List<Status> status = actionStatusList.stream().map(ActionStatus::getStatus)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(status).containsOnly(expectedActionStates);
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
public abstract class AmqpServiceIntegrationTest extends AbstractAmqpIntegrationTest {
|
||||
|
||||
protected static final String TENANT_EXIST = "DEFAULT";
|
||||
protected static final String REGISTER_TARGET = "NewDmfTarget";
|
||||
protected static final String CREATED_BY = "CONTROLLER_PLUG_AND_PLAY";
|
||||
|
||||
private DeadletterListener deadletterListener;
|
||||
@@ -105,23 +104,24 @@ public abstract class AmqpServiceIntegrationTest extends AbstractAmqpIntegration
|
||||
return distributionSet;
|
||||
}
|
||||
|
||||
protected DistributionSetAssignmentResult registerTargetAndAssignDistributionSet() {
|
||||
protected DistributionSetAssignmentResult registerTargetAndAssignDistributionSet(final String controllerId) {
|
||||
distributionSet = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
||||
return registerTargetAndAssignDistributionSet(distributionSet.getId(), TargetUpdateStatus.REGISTERED,
|
||||
distributionSet.getModules());
|
||||
distributionSet.getModules(), controllerId);
|
||||
}
|
||||
|
||||
protected DistributionSetAssignmentResult registerTargetAndAssignDistributionSet(final Long assignDs,
|
||||
final TargetUpdateStatus expectedStatus, final Set<SoftwareModule> expectedSoftwareModulesInMessage) {
|
||||
registerAndAssertTargetWithExistingTenant(REGISTER_TARGET, 1, expectedStatus, CREATED_BY);
|
||||
final TargetUpdateStatus expectedStatus, final Set<SoftwareModule> expectedSoftwareModulesInMessage,
|
||||
final String controllerId) {
|
||||
registerAndAssertTargetWithExistingTenant(controllerId, 1, expectedStatus, CREATED_BY);
|
||||
|
||||
final DistributionSetAssignmentResult assignmentResult = assignDistributionSet(assignDs, REGISTER_TARGET);
|
||||
assertDownloadAndInstallMessage(expectedSoftwareModulesInMessage);
|
||||
final DistributionSetAssignmentResult assignmentResult = assignDistributionSet(assignDs, controllerId);
|
||||
assertDownloadAndInstallMessage(expectedSoftwareModulesInMessage, controllerId);
|
||||
return assignmentResult;
|
||||
}
|
||||
|
||||
protected void assertCancelActionMessage(final Long actionId) {
|
||||
final Message replyMessage = assertReplyMessageHeader(EventTopic.CANCEL_DOWNLOAD);
|
||||
protected void assertCancelActionMessage(final Long actionId, final String controllerId) {
|
||||
final Message replyMessage = assertReplyMessageHeader(EventTopic.CANCEL_DOWNLOAD, controllerId);
|
||||
|
||||
final Long actionUpdateStatus = (Long) getDmfClient().getMessageConverter().fromMessage(replyMessage);
|
||||
assertThat(actionUpdateStatus).isEqualTo(actionId);
|
||||
@@ -138,8 +138,8 @@ public abstract class AmqpServiceIntegrationTest extends AbstractAmqpIntegration
|
||||
assertThat(headers.get(MessageHeaderKey.TYPE)).isEqualTo(MessageType.THING_DELETED.toString());
|
||||
}
|
||||
|
||||
protected void assertDownloadAndInstallMessage(final Set<SoftwareModule> dsModules) {
|
||||
final Message replyMessage = assertReplyMessageHeader(EventTopic.DOWNLOAD_AND_INSTALL);
|
||||
protected void assertDownloadAndInstallMessage(final Set<SoftwareModule> dsModules, final String controllerId) {
|
||||
final Message replyMessage = assertReplyMessageHeader(EventTopic.DOWNLOAD_AND_INSTALL, controllerId);
|
||||
assertAllTargetsCount(1);
|
||||
|
||||
final DmfDownloadAndUpdateRequest downloadAndUpdateRequest = (DmfDownloadAndUpdateRequest) getDmfClient()
|
||||
@@ -148,8 +148,7 @@ public abstract class AmqpServiceIntegrationTest extends AbstractAmqpIntegration
|
||||
Assert.assertThat(dsModules,
|
||||
SoftwareModuleJsonMatcher.containsExactly(downloadAndUpdateRequest.getSoftwareModules()));
|
||||
|
||||
final Target updatedTarget = waitUntilIsPresent(
|
||||
() -> targetManagement.findTargetByControllerID(REGISTER_TARGET));
|
||||
final Target updatedTarget = waitUntilIsPresent(() -> targetManagement.findTargetByControllerID(controllerId));
|
||||
|
||||
assertThat(updatedTarget.getSecurityToken()).isEqualTo(downloadAndUpdateRequest.getTargetSecurityToken());
|
||||
}
|
||||
@@ -165,28 +164,28 @@ public abstract class AmqpServiceIntegrationTest extends AbstractAmqpIntegration
|
||||
});
|
||||
}
|
||||
|
||||
protected Long cancelAction(final Long actionId) {
|
||||
protected Long cancelAction(final Long actionId, final String controllerId) {
|
||||
deploymentManagement.cancelAction(actionId);
|
||||
assertCancelActionMessage(actionId);
|
||||
assertCancelActionMessage(actionId, controllerId);
|
||||
return actionId;
|
||||
}
|
||||
|
||||
protected Long registerTargetAndCancelActionId() {
|
||||
final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet();
|
||||
return cancelAction(assignmentResult.getActions().get(0));
|
||||
protected Long registerTargetAndCancelActionId(final String controllerId) {
|
||||
final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet(controllerId);
|
||||
return cancelAction(assignmentResult.getActions().get(0), controllerId);
|
||||
}
|
||||
|
||||
protected void assertAllTargetsCount(final long expectedTargetsCount) {
|
||||
assertThat(targetManagement.countTargetsAll()).isEqualTo(expectedTargetsCount);
|
||||
}
|
||||
|
||||
private Message assertReplyMessageHeader(final EventTopic eventTopic) {
|
||||
private Message assertReplyMessageHeader(final EventTopic eventTopic, final String controllerId) {
|
||||
verifyReplyToListener();
|
||||
final Message replyMessage = replyToListener.getEventTopicMessages().get(eventTopic);
|
||||
assertAllTargetsCount(1);
|
||||
final Map<String, Object> headers = replyMessage.getMessageProperties().getHeaders();
|
||||
assertThat(headers.get(MessageHeaderKey.TOPIC)).isEqualTo(eventTopic.toString());
|
||||
assertThat(headers.get(MessageHeaderKey.THING_ID)).isEqualTo(REGISTER_TARGET);
|
||||
assertThat(headers.get(MessageHeaderKey.THING_ID)).isEqualTo(controllerId);
|
||||
assertThat(headers.get(MessageHeaderKey.TENANT)).isEqualTo(TENANT_EXIST);
|
||||
assertThat(headers.get(MessageHeaderKey.TYPE)).isEqualTo(MessageType.EVENT.toString());
|
||||
return replyMessage;
|
||||
@@ -209,20 +208,18 @@ public abstract class AmqpServiceIntegrationTest extends AbstractAmqpIntegration
|
||||
assertTarget(registerdTarget, expectedTargetStatus, createdBy);
|
||||
}
|
||||
|
||||
protected void registerSameTargetAndAssertBasedOnLastPolling(final String target,
|
||||
final int existingTargetsAfterCreation, final TargetUpdateStatus expectedTargetStatus,
|
||||
final Long pollingTimeTargetOld) {
|
||||
createAndSendTarget(target, TENANT_EXIST);
|
||||
final Target registerdTarget = waitUntilIsPresent(
|
||||
() -> findTargetBasedOnNewPolltime(target, pollingTimeTargetOld));
|
||||
protected void registerSameTargetAndAssertBasedOnVersion(final String controllerId,
|
||||
final int existingTargetsAfterCreation, final TargetUpdateStatus expectedTargetStatus) {
|
||||
final int version = controllerManagement.findByControllerId(controllerId).get().getOptLockRevision();
|
||||
createAndSendTarget(controllerId, TENANT_EXIST);
|
||||
final Target registeredTarget = waitUntilIsPresent(() -> findTargetBasedOnNewVersion(controllerId, version));
|
||||
assertAllTargetsCount(existingTargetsAfterCreation);
|
||||
assertThat(registerdTarget.getUpdateStatus()).isEqualTo(expectedTargetStatus);
|
||||
assertThat(registeredTarget.getUpdateStatus()).isEqualTo(expectedTargetStatus);
|
||||
}
|
||||
|
||||
private Optional<Target> findTargetBasedOnNewPolltime(final String controllerId, final Long pollingTimeTargetOld) {
|
||||
private Optional<Target> findTargetBasedOnNewVersion(final String controllerId, final int version) {
|
||||
final Optional<Target> target2 = controllerManagement.findByControllerId(controllerId);
|
||||
final Long pollingTimeTargetNew = target2.get().getLastTargetQuery();
|
||||
if (pollingTimeTargetOld < pollingTimeTargetNew) {
|
||||
if (version < target2.get().getOptLockRevision()) {
|
||||
return target2;
|
||||
}
|
||||
return Optional.empty();
|
||||
@@ -244,7 +241,7 @@ public abstract class AmqpServiceIntegrationTest extends AbstractAmqpIntegration
|
||||
messageProperties.getHeaders().put(MessageHeaderKey.TYPE, MessageType.THING_CREATED.toString());
|
||||
messageProperties.setReplyTo(DmfTestConfiguration.REPLY_TO_EXCHANGE);
|
||||
|
||||
return createMessage("", messageProperties);
|
||||
return createMessage(null, messageProperties);
|
||||
}
|
||||
|
||||
protected MessageProperties createMessagePropertiesWithTenant(final String tenant) {
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2015 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
|
||||
#
|
||||
|
||||
# RabbitMQ
|
||||
spring.rabbitmq.host=localhost
|
||||
|
||||
spring.jpa.database=H2
|
||||
flyway.sqlMigrationSuffix=${spring.jpa.database}.sql
|
||||
|
||||
# Default tenant configuration properties
|
||||
hawkbit.server.tenant.configuration.authentication-header-enabled.keyName=authentication.header.enabled
|
||||
hawkbit.server.tenant.configuration.authentication-header-enabled.defaultValue=false
|
||||
hawkbit.server.tenant.configuration.authentication-header-enabled.dataType=java.lang.Boolean
|
||||
hawkbit.server.tenant.configuration.authentication-header-enabled.validator=org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationBooleanValidator
|
||||
|
||||
hawkbit.server.tenant.configuration.authentication-header-authority.keyName=authentication.header.authority
|
||||
hawkbit.server.tenant.configuration.authentication-header-authority.defaultValue=false
|
||||
|
||||
hawkbit.server.tenant.configuration.authentication-targettoken-enabled.keyName=authentication.targettoken.enabled
|
||||
hawkbit.server.tenant.configuration.authentication-targettoken-enabled.defaultValue=false
|
||||
hawkbit.server.tenant.configuration.authentication-targettoken-enabled.dataType=java.lang.Boolean
|
||||
hawkbit.server.tenant.configuration.authentication-targettoken-enabled.validator=org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationBooleanValidator
|
||||
|
||||
hawkbit.server.tenant.configuration.authentication-gatewaytoken-enabled.keyName=authentication.gatewaytoken.enabled
|
||||
hawkbit.server.tenant.configuration.authentication-gatewaytoken-enabled.defaultValue=false
|
||||
hawkbit.server.tenant.configuration.authentication-gatewaytoken-enabled.dataType=java.lang.Boolean
|
||||
hawkbit.server.tenant.configuration.authentication-gatewaytoken-enabled.validator=org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationBooleanValidator
|
||||
|
||||
hawkbit.server.tenant.configuration.authentication-gatewaytoken-key.keyName=authentication.gatewaytoken.key
|
||||
hawkbit.server.tenant.configuration.authentication-gatewaytoken-key.defaultValue=false
|
||||
|
||||
hawkbit.server.tenant.configuration.anonymous-download-enabled.keyName=anonymous.download.enabled
|
||||
hawkbit.server.tenant.configuration.anonymous-download-enabled.defaultValue=false
|
||||
hawkbit.server.tenant.configuration.anonymous-download-enabled.dataType=java.lang.Boolean
|
||||
hawkbit.server.tenant.configuration.anonymous-download-enabled.validator=org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationBooleanValidator
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2015 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
|
||||
|
||||
-->
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml" />
|
||||
|
||||
<logger name="org.eclipse.hawkbit.eventbus.DeadEventListener" level="WARN" />
|
||||
<Logger name="org.springframework.boot.actuate.audit.listener.AuditListener" level="WARN" />
|
||||
|
||||
<Logger name="org.hibernate.validator.internal.util.Version" level="WARN" />
|
||||
|
||||
<Logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN" />
|
||||
<Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN" />
|
||||
<Logger name="org.apache.tomcat.jdbc.pool.ConnectionPool" level="DEBUG" />
|
||||
<Logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR" />
|
||||
|
||||
|
||||
<!-- <Logger name="org.eclipse.hawkbit.rest.util.MockMvcResultPrinter" level="DEBUG" /> -->
|
||||
|
||||
<!-- Security Log with hints on potential attacks -->
|
||||
<logger name="server-security" level="INFO" />
|
||||
|
||||
<Root level="INFO">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</Root>
|
||||
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user