diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ResourceTypeUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ResourceTypeUtil.java index 259cefc6abd..ace476efb5a 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ResourceTypeUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ResourceTypeUtil.java @@ -751,4 +751,22 @@ public static ErrorSelectorType getConnectorErrorCriticality(ResourceType resour } return consistency.getConnectorErrorCriticality(); } + + public static boolean isInMaintenance(ResourceType resource) { + if (resource == null) + return false; + + AdministrativeOperationalStateType administrativeOperationalState = resource.getAdministrativeOperationalState(); + if (administrativeOperationalState == null) + return false; + + AdministrativeAvailabilityStatusType administrativeAvailabilityStatus = administrativeOperationalState.getAdministrativeAvailabilityStatus(); + if (administrativeAvailabilityStatus == null) + return false; + + if (AdministrativeAvailabilityStatusType.MAINTENANCE == administrativeAvailabilityStatus) + return true; + + return false; + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java index ca68c1a2424..8d829420a9c 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java @@ -17,6 +17,7 @@ import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.repo.common.util.RepoCommonUtils; import com.evolveum.midpoint.schema.cache.CacheConfigurationManager; +import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.task.api.*; import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -199,6 +200,9 @@ public TaskWorkBucketProcessingResult run(RunningTask localCoordinatorTask, Work try { resource = provisioningService.getObject(ResourceType.class, resourceOid, null, localCoordinatorTask, opResult); + if (ResourceTypeUtil.isInMaintenance(resource.asObjectable())) + throw new MaintenanceException("Resource " + resource + " is in the maintenance"); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.MODEL, prismContext); objectclassDef = ModelImplUtils.determineObjectClass(refinedSchema, localCoordinatorTask); } catch (ObjectNotFoundException ex) { @@ -206,6 +210,11 @@ public TaskWorkBucketProcessingResult run(RunningTask localCoordinatorTask, Work processErrorPartial(runResult, "Resource does not exist, OID: " + resourceOid, ex, TaskRunResultStatus.PERMANENT_ERROR, opResult); return runResult; + } catch (MaintenanceException ex) { + LOGGER.warn("Reconciliation: {}-{}", new Object[]{ex.getMessage(), ex}); + opResult.recordHandledError(ex.getMessage(), ex); + runResult.setRunResultStatus(TaskRunResultStatus.TEMPORARY_ERROR); // Resource is in the maintenance, do not suspend the task + return runResult; } catch (CommunicationException ex) { // Error, but not critical. Just try later. processErrorPartial(runResult, "Communication error", ex, TaskRunResultStatus.TEMPORARY_ERROR, opResult); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SyncTaskHelper.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SyncTaskHelper.java index ef51bca52cb..4e94e3815b5 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SyncTaskHelper.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SyncTaskHelper.java @@ -159,6 +159,9 @@ void processException(Trace LOGGER, Throwable t, OperationResult opResult, TaskR // This is bad. The resource or task or something like that does not exist. Permanent problem. opResult.recordFatalError("A required object does not exist, OID: " + oid, t); setRunResultStatus(t, partition, CriticalityType.FATAL, runResult); + } else if (t instanceof MaintenanceException) { + opResult.recordHandledError("Maintenance exception: "+t.getMessage(), t); + runResult.setRunResultStatus(TaskRunResult.TaskRunResultStatus.TEMPORARY_ERROR); // Resource is in the maintenance, do not suspend the task } else if (t instanceof CommunicationException) { LOGGER.error("{}: Communication error: {}", ctx, t.getMessage(), t); // Error, but not critical. Just try later. diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java index 11fe4aa52f7..173a90bc17f 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java @@ -13,7 +13,6 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; -import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.delta.ItemDeltaCollectionsUtil; import com.evolveum.midpoint.prism.path.ItemPath; @@ -24,6 +23,7 @@ import com.evolveum.midpoint.repo.api.SystemConfigurationChangeListener; import com.evolveum.midpoint.schema.cache.CacheConfigurationManager; import com.evolveum.midpoint.schema.cache.CacheType; +import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.Validate; @@ -44,7 +44,6 @@ import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.query.NoneFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; -import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.provisioning.api.ConstraintViolationConfirmer; import com.evolveum.midpoint.provisioning.api.ConstraintsCheckingResult; @@ -70,7 +69,6 @@ import com.evolveum.midpoint.schema.statistics.ConnectorOperationalStatus; import com.evolveum.midpoint.schema.util.ObjectQueryUtil; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; -import com.evolveum.midpoint.schema.util.SchemaDebugUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.logging.Trace; @@ -341,11 +339,17 @@ public int synchronize(ResourceShadowDiscriminator shadowCoordinates, Task task, PrismObject resource = getObject(ResourceType.class, resourceOid, null, task, result); ResourceType resourceType = resource.asObjectable(); + if (ResourceTypeUtil.isInMaintenance(resourceType)) + throw new MaintenanceException("Resource " + resource + " is in the maintenance"); + LOGGER.trace("Start synchronization of resource {} ", resourceType); liveSyncResult = liveSynchronizer.synchronize(shadowCoordinates, task, taskPartition, result); LOGGER.debug("Synchronization of {} done, result: {}", resource, liveSyncResult); + } catch (MaintenanceException e) { + result.recordHandledError(e.getMessage(), e); + throw e; } catch (ObjectNotFoundException | CommunicationException | SchemaException | SecurityViolationException | ConfigurationException | ExpressionEvaluationException | RuntimeException | Error e) { ProvisioningUtil.recordFatalError(LOGGER, result, null, e); result.summarize(true); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java index 113bc269176..de807950330 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java @@ -190,7 +190,7 @@ public PrismObject getShadow(String oid, PrismObject rep throw e; } - if (ProvisioningUtil.resourceIsInMaintenance(resource)) { + if (ResourceTypeUtil.isInMaintenance(resource)) { try { MaintenanceException ex = new MaintenanceException("Resource " + resource + " is in the maintenance"); PrismObject handledShadow = handleGetError(ctx, repositoryShadow, rootOptions, ex, task, parentResult); @@ -559,7 +559,7 @@ private String addShadowAttempt(ProvisioningContext ctx, LOGGER.trace("ADD {}: resource operation, execution starting", shadowToAdd); try { - if (ProvisioningUtil.resourceIsInMaintenance(ctx.getResource())) { + if (ResourceTypeUtil.isInMaintenance(ctx.getResource())) { throw new MaintenanceException("Resource " + ctx.getResource() + " is in the maintenance"); // this tells mp to create pending delta } @@ -1008,7 +1008,7 @@ private String modifyShadowAttempt(ProvisioningContext ctx, ConnectorOperationOptions connOptions = createConnectorOperationOptions(ctx, options, parentResult); try { - if (ProvisioningUtil.resourceIsInMaintenance(ctx.getResource())) { + if (ResourceTypeUtil.isInMaintenance(ctx.getResource())) { throw new MaintenanceException("Resource " + ctx.getResource() + " is in the maintenance"); } @@ -1264,7 +1264,7 @@ private PrismObject deleteShadowAttempt(ProvisioningContext ctx, LOGGER.trace("DELETE {}: resource deletion, execution starting", repoShadow); try { - if (ProvisioningUtil.resourceIsInMaintenance(ctx.getResource())) { + if (ResourceTypeUtil.isInMaintenance(ctx.getResource())) { throw new MaintenanceException("Resource " + ctx.getResource() + " is in the maintenance"); } @@ -1399,7 +1399,7 @@ private RefreshShadowOperation refreshShadowPendingOperations(ProvisioningContex return rso; } - if (ProvisioningUtil.resourceIsInMaintenance(ctx.getResource())) { + if (ResourceTypeUtil.isInMaintenance(ctx.getResource())) { LOGGER.trace("Skipping refresh of {} pending operations because resource shadow is in the maintenance.", repoShadow); RefreshShadowOperation rso = new RefreshShadowOperation(); rso.setRefreshedShadow(repoShadow); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/shadowmanager/ShadowManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/shadowmanager/ShadowManager.java index 3f11ef694ec..4fb5e2c6680 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/shadowmanager/ShadowManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/shadowmanager/ShadowManager.java @@ -1188,7 +1188,7 @@ private PendingOperationType checkAndRec ResourceType resource = ctx.getResource(); ResourceConsistencyType consistencyType = resource.getConsistency(); - boolean isInMaintenance = ProvisioningUtil.resourceIsInMaintenance(ctx.getResource()); + boolean isInMaintenance = ResourceTypeUtil.isInMaintenance(ctx.getResource()); Boolean avoidDuplicateOperations; if (isInMaintenance) { diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java index 80732008e59..7d4220e1892 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java @@ -586,24 +586,6 @@ public static boolean resourceReadIsCachingOnly(ResourceType resource) { return Boolean.TRUE.equals(readCapabilityType.isCachingOnly()); } - public static boolean resourceIsInMaintenance(ResourceType resource) { - if (resource == null) - return false; - - AdministrativeOperationalStateType administrativeOperationalState = resource.getAdministrativeOperationalState(); - if (administrativeOperationalState == null) - return false; - - AdministrativeAvailabilityStatusType administrativeAvailabilityStatus = administrativeOperationalState.getAdministrativeAvailabilityStatus(); - if (administrativeAvailabilityStatus == null) - return false; - - if (AdministrativeAvailabilityStatusType.MAINTENANCE == administrativeAvailabilityStatus) - return true; - - return false; - } - public static Duration getGracePeriod(ProvisioningContext ctx) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException { Duration gracePeriod = null; ResourceConsistencyType consistency = ctx.getResource().getConsistency(); diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestResourceInMaintenance.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestResourceInMaintenance.java index 33989ff22b3..b8d11e6ae8e 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestResourceInMaintenance.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestResourceInMaintenance.java @@ -11,12 +11,15 @@ package com.evolveum.midpoint.testing.story; +import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import java.io.File; import java.io.FileInputStream; import javax.xml.namespace.QName; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; @@ -47,16 +50,19 @@ public class TestResourceInMaintenance extends AbstractStoryTest { private static final File RESOURCE_CSV_FILE = new File(TEST_DIR, "csv-resource1.xml"); private static final File RESOURCE_CSV_CONTENT_FILE = new File(TEST_DIR, "data-resource1.csv"); + private static final File ROLE1_FILE = new File(TEST_DIR, "role1.xml"); private static String sourceFilePath; private static final File SHADOW_FILE = new File(TEST_DIR, "shadow-user1.xml"); - private static final File USER1_FILE = new File(TEST_DIR, "user1.xml"); - private static final File USER2_FILE = new File(TEST_DIR, "user2.xml"); + private static final File USERS_FILE = new File(TEST_DIR, "users.xml"); private static final String RESOURCE_OID = "25dd0010-5115-4ac0-960f-4889d1b960ff"; private static final String SHADOW_OID = "c4071f2e-3f8d-4301-9027-c57033c702ff"; private static final String USER1_OID = "cdc33185-c817-4be7-8158-8f338824cdff"; private static final String USER2_OID = "cdc33185-c817-4be7-8158-8f3388241234"; + private static final String USER3_OID = "cdc33185-c817-4be7-8158-8f3388245678"; + private static final String USER4_OID = "cdc33185-c817-4be7-8158-8f33882456bb"; + private static final String ROLE1_OID = "6ec32c86-66d4-4101-a25f-931db8d1e999"; private static final QName CSV_ATTRIBUTE_DESC = new QName(MidPointConstants.NS_RI, "description"); private static final QName CSV_ATTRIBUTE_FULLNAME = new QName(MidPointConstants.NS_RI, "fullname"); @@ -113,8 +119,8 @@ SchemaConstants.ICF_CONFIGURATION_PROPERTIES, new QName(NS_RESOURCE_CSV, "filePa display("System config", systemConfiguration); importObjectFromFile(SHADOW_FILE); - importObjectFromFile(USER1_FILE); - importObjectFromFile(USER2_FILE); + importObjectFromFile(USERS_FILE); + importObjectFromFile(ROLE1_FILE); // Turn maintenance mode ON: switchResourceMaintenance(AdministrativeAvailabilityStatusType.MAINTENANCE, task, result); @@ -266,7 +272,9 @@ public void test040CreateNewAccount() throws Exception { result2.computeStatus(); TestUtil.assertSuccess(result2); - TestUtil.assertInProgress("resource in the maintenance pending delta", result); + + int noOfLinks = getUser(USER2_OID).asObjectable().getLinkRef().size(); + assertEquals(noOfLinks, 1); // check that consequent recompute hasnt created second shadow // double check that nothing changed in the shadow after recompute: assertRepoShadow(newShadowOid) @@ -439,6 +447,7 @@ public void test080ApplyPendingDelete() throws Exception { String shadowOid = getLinkRefOid(USER2_OID, RESOURCE_OID); PrismObject shadow = getShadowModel(shadowOid); ShadowAsserter.forShadow(shadow) + .display("Shadow before delete") .assertIsExists() .end(); @@ -472,6 +481,159 @@ public void test080ApplyPendingDelete() throws Exception { .end(); } + @Test + public void test090CreateAndDeleteAccountWithRole() throws Exception { + Task task = getTestTask(); + OperationResult result = task.getResult(); + + // Turn maintenance mode ON: + switchResourceMaintenance(AdministrativeAvailabilityStatusType.MAINTENANCE, task, result); + + assignRole(USER3_OID, ROLE1_OID, task, result); + + result.computeStatus(); + display(result); + + TestUtil.assertInProgress("resource in the maintenance pending delta", result); + + String newShadowOid = getLinkRefOid(USER3_OID, RESOURCE_OID); + assertNotNull(newShadowOid); + + assertRepoShadow(newShadowOid) + .display(getTestNameShort() + " Shadow after") + .assertKind(ShadowKindType.ACCOUNT) + .assertIsNotExists() + .assertNotDead() + .assertNoLegacyConsistency() + .attributes() + .assertAttributes(CSV_ATTRIBUTE_USERNAME) // checks main attributes section, not attributes in the pending delta + .end() + .pendingOperations() + .singleOperation() + .display() + .assertType(PendingOperationTypeType.RETRY) + .assertExecutionStatus(PendingOperationExecutionStatusType.EXECUTING) + .assertResultStatus(OperationResultStatusType.IN_PROGRESS) + .assertAttemptNumber(1) + .delta() + .display() + .assertAdd(); + + // lets try recompute just for fun, mp should do nothing and report success: + OperationResult result2 = createOperationResult(); + modelService.recompute(UserType.class, USER3_OID, executeOptions().reconcile(), task, result2); + result2.computeStatus(); + + TestUtil.assertSuccess(result2); + + assertUser(USER3_OID, getTestNameShort()).assertLinks(1); // check that consequent recompute hasnt created second shadow + + // double check that nothing changed in the shadow after recompute: + assertRepoShadow(newShadowOid) + .display(getTestNameShort() + " Shadow after") + .assertKind(ShadowKindType.ACCOUNT) + .assertIsNotExists() + .assertNotDead() + .pendingOperations() + .singleOperation() + .display() + .assertType(PendingOperationTypeType.RETRY) + .assertExecutionStatus(PendingOperationExecutionStatusType.EXECUTING) + .assertResultStatus(OperationResultStatusType.IN_PROGRESS) + .assertAttemptNumber(1) + .delta() + .display() + .assertAdd(); + + // now delete account: + OperationResult result3 = createOperationResult(); + unassignRole(USER3_OID, ROLE1_OID, task, result3); + result3.computeStatus(); + TestUtil.assertInProgress("resource in the maintenance pending delta", result3); + + assertModelShadowNoFetch(newShadowOid) + .display("Shadow after delete") + .assertKind(ShadowKindType.ACCOUNT) + .assertNotDead() + .assertNoLegacyConsistency() + .attributes() + .assertHasPrimaryIdentifier() + .end() + .pendingOperations() + .assertOperations(2) // 1x create + 1x delete + .deleteOperation() + .assertExecutionStatus(PendingOperationExecutionStatusType.EXECUTING) + .assertResultStatus(OperationResultStatusType.IN_PROGRESS) + .assertAttemptNumber(1) + .delta() + .display() + .assertDelete() + .end() + .end(); + + // Cancel maintenance mode: + switchResourceMaintenance(AdministrativeAvailabilityStatusType.OPERATIONAL, task, result); + + // Apply pending create + delete delta: + OperationResult result4 = createOperationResult(); + modelService.recompute(UserType.class, USER2_OID, executeOptions().reconcile(), task, result4); + result4.computeStatus(); + TestUtil.assertSuccess(result4); + + // Check that nothing really happened on the resource: + PrismObject shadowDeleted = getShadowModel(newShadowOid); + ShadowAsserter.forShadow(shadowDeleted) + .assertIsNotExists() + .end(); + } + + @Test + public void test100CreateAndDeleteAccountWithResourceAssignment() throws Exception { + Task task = getTestTask(); + OperationResult result = task.getResult(); + + // Turn maintenance mode ON: + switchResourceMaintenance(AdministrativeAvailabilityStatusType.MAINTENANCE, task, result); + + ObjectDelta userDelta = createAccountAssignmentUserDelta(USER4_OID, RESOURCE_OID, "default", true); + modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); + result.computeStatus(); + + TestUtil.assertInProgress("resource in the maintenance pending delta", result); + + String newShadowOid = getLinkRefOid(USER4_OID, RESOURCE_OID); + assertNotNull(newShadowOid); + + assertRepoShadow(newShadowOid) + .display(getTestNameShort() + " Shadow after") + .assertKind(ShadowKindType.ACCOUNT) + .assertIsNotExists() + .assertNotDead() + .assertNoLegacyConsistency() + .attributes() + .assertAttributes(CSV_ATTRIBUTE_USERNAME) // checks main attributes section, not attributes in the pending delta + .end() + .pendingOperations() + .singleOperation() + .display() + .assertType(PendingOperationTypeType.RETRY) + .assertExecutionStatus(PendingOperationExecutionStatusType.EXECUTING) + .assertResultStatus(OperationResultStatusType.IN_PROGRESS) + .assertAttemptNumber(1) + .delta() + .display() + .assertAdd(); + + // lets try recompute just for fun, mp should do nothing and report success: + OperationResult result2 = createOperationResult(); + modelService.recompute(UserType.class, USER4_OID, executeOptions().reconcile(), task, result2); + result2.computeStatus(); + + TestUtil.assertSuccess(result2); + + assertUser(USER4_OID, getTestNameShort()).assertLinks(1); // check that consequent recompute hasnt created second shadow + } + private void switchResourceMaintenance (AdministrativeAvailabilityStatusType mode, Task task, OperationResult result) throws Exception { ObjectDelta objectDelta = prismContext.deltaFactory().object() .createModificationReplaceProperty(ResourceType.class, RESOURCE_OID, ItemPath.create(ResourceType.F_ADMINISTRATIVE_OPERATIONAL_STATE, diff --git a/testing/story/src/test/resources/resource-in-maintenance/role1.xml b/testing/story/src/test/resources/resource-in-maintenance/role1.xml new file mode 100644 index 00000000000..faae4e0d82a --- /dev/null +++ b/testing/story/src/test/resources/resource-in-maintenance/role1.xml @@ -0,0 +1,9 @@ + + CSV1 LR + + + + + + + diff --git a/testing/story/src/test/resources/resource-in-maintenance/user1.xml b/testing/story/src/test/resources/resource-in-maintenance/user1.xml deleted file mode 100644 index 8c9dffc6e04..00000000000 --- a/testing/story/src/test/resources/resource-in-maintenance/user1.xml +++ /dev/null @@ -1,9 +0,0 @@ - - user1 - Darth Vader - sith - - - enabled - - diff --git a/testing/story/src/test/resources/resource-in-maintenance/user2.xml b/testing/story/src/test/resources/resource-in-maintenance/user2.xml deleted file mode 100644 index 4baf44e49b7..00000000000 --- a/testing/story/src/test/resources/resource-in-maintenance/user2.xml +++ /dev/null @@ -1,8 +0,0 @@ - - user2 - R2-D2 - robot - - enabled - - diff --git a/testing/story/src/test/resources/resource-in-maintenance/users.xml b/testing/story/src/test/resources/resource-in-maintenance/users.xml new file mode 100644 index 00000000000..b6a0a7e5a51 --- /dev/null +++ b/testing/story/src/test/resources/resource-in-maintenance/users.xml @@ -0,0 +1,35 @@ + + + user1 + Darth Vader + sith + + + enabled + + + + user2 + R2-D2 + robot + + enabled + + + + user3 + C-3PO + robot + + enabled + + + + user4 + Death Star + space station + + enabled + + +