Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
KaterynaHonchar committed Nov 25, 2019
2 parents e0ad284 + 7225c8a commit 40092ad
Show file tree
Hide file tree
Showing 23 changed files with 296 additions and 87 deletions.
2 changes: 1 addition & 1 deletion build-system/pom.xml
Expand Up @@ -765,7 +765,7 @@
<dependency>
<groupId>com.evolveum.polygon</groupId>
<artifactId>connector-ldap</artifactId>
<version>2.3</version>
<version>2.4</version>
</dependency>
<!-- End connectors -->
<dependency>
Expand Down
Expand Up @@ -29,18 +29,19 @@
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ImportOptionsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ExecuteScriptType;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ScriptingExpressionType;

/**
* @author lazyman
* @author skublik
*/
public class PostInitialDataImport extends DataImport{
public class PostInitialDataImport extends DataImport {

private static final Trace LOGGER = TraceManager.getTrace(PostInitialDataImport.class);

private static final String OPERATION_EXECUTE_SCRIPT = DOT_CLASS + "executeScript";

private static final String SUFFIX_FOR_IMPORTED_FILE = "done";
private static final String XML_SUFFIX = "xml";

Expand All @@ -63,48 +64,41 @@ public void init() throws SchemaException {

SecurityContext securityContext = provideFakeSecurityContext();

int countImpotredObjects = 0;
int countImportedObjects = 0;
int countExecutedScripts = 0;

for (File file : files) {
if(FilenameUtils.getExtension(file.getName()).equals(SUFFIX_FOR_IMPORTED_FILE)) {
String fileExtension = FilenameUtils.getExtension(file.getName());
if (fileExtension.equals(SUFFIX_FOR_IMPORTED_FILE)) {
continue;
}
if(!FilenameUtils.getExtension(file.getName()).equals(XML_SUFFIX)) {
if (!fileExtension.equals(XML_SUFFIX)) {
LOGGER.warn("Post-initial import support only xml files. Actual file: " + file.getName());
continue;
}
Item item = null;
Item<?,?> item = null;
try {
item = prismContext.parserFor(file).parseItem();
} catch (Exception ex) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't parse file {}", ex, file.getName());
mainResult.recordFatalError("Couldn't parse file '" + file.getName() + "'", ex);
}

if(item instanceof PrismProperty && (((PrismProperty)item).getRealValue() instanceof ScriptingExpressionType || ((PrismProperty)item).getRealValue() instanceof ExecuteScriptType)){
PrismProperty<Object> expression = (PrismProperty<Object>)item;
Boolean executeScript = executeScript(expression, file, task, mainResult);
if (executeScript) {
file.renameTo(new File(file.getPath() + "." + SUFFIX_FOR_IMPORTED_FILE));
if (item instanceof PrismProperty && (item.getRealValue() instanceof ScriptingExpressionType || item.getRealValue() instanceof ExecuteScriptType)) {
//noinspection unchecked
PrismProperty<Object> expression = (PrismProperty<Object>) item;
if (executeScript(expression, file, task, mainResult)) {
markAsDone(file);
countExecutedScripts++;
} else {
break;
}
} else {
try {
LOGGER.debug("Considering post-initial import of file {}.", file.getName());

Boolean importObject = importObject(file, task, mainResult);
if (importObject) {
file.renameTo(new File(file.getPath() + "." + SUFFIX_FOR_IMPORTED_FILE));
countImpotredObjects++;
} else {
break;
}
} catch (Exception ex) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't import file {}", ex, file.getName());
mainResult.recordFatalError("Couldn't import file '" + file.getName() + "'", ex);
if (importObject(file, task, mainResult)) {
markAsDone(file);
countImportedObjects++;
} else {
break;
}
}
}
Expand All @@ -113,45 +107,41 @@ public void init() throws SchemaException {

mainResult.recomputeStatus("Couldn't import objects.");

LOGGER.info("Post-initial object import finished ({} objects imported, {} scripts executed)", countImpotredObjects, countExecutedScripts);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Initialization status:\n" + mainResult.debugDump());
LOGGER.info("Post-initial object import finished ({} objects imported, {} scripts executed)", countImportedObjects, countExecutedScripts);
LOGGER.trace("Initialization status:\n{}", mainResult.debugDumpLazily());
}

private void markAsDone(File file) {
if (!file.renameTo(new File(file.getPath() + "." + SUFFIX_FOR_IMPORTED_FILE))) {
LOGGER.warn("Renaming {} to indicate 'done' status was not successful", file);
}
}

/**
* @param object
* @param task
* @param mainResult
* @return true if it was success, otherwise false
*/
private <O extends ObjectType> Boolean importObject(File file, Task task, OperationResult mainResult) {
private boolean importObject(File file, Task task, OperationResult mainResult) {
OperationResult result = mainResult.createSubresult(OPERATION_IMPORT_OBJECT);
try {
LOGGER.info("Starting post-initial import of file {}.", file.getName());
ImportOptionsType options = new ImportOptionsType();
options.overwrite(true);
model.importObjectsFromFile(file, options, task, result);
result.recordSuccess();
return true;
} catch (Exception e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't import object from file {}: ", e, file.getName(), e.getMessage());
result.recordFatalError(e);

LOGGER.info("\n" + result.debugDump());
return false;
}
LOGGER.info("Starting post-initial import of file {}.", file.getName());
ImportOptionsType options = new ImportOptionsType();
options.overwrite(true);
model.importObjectsFromFile(file, options, task, result);
result.recordSuccess();
return true;
} catch (Exception e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't import object from file {}: ", e, file.getName(), e.getMessage());
result.recordFatalError(e);
LOGGER.info("\n{}", result.debugDump());
return false;
}
}

/**
* @param expression
* @param file
* @param task
* @param mainResult
* @return rue if it was success, otherwise false
* @return true if it was success, otherwise false
*/
private <O extends ObjectType> Boolean executeScript(PrismProperty<Object> expression, File file, Task task, OperationResult mainResult) {
OperationResult result = mainResult.createSubresult(OPERATION_IMPORT_OBJECT);
private boolean executeScript(PrismProperty<Object> expression, File file, Task task, OperationResult mainResult) {
OperationResult result = mainResult.createSubresult(OPERATION_EXECUTE_SCRIPT);

try {
LOGGER.info("Starting post-initial execute script from file {}.", file.getName());
Expand All @@ -163,7 +153,7 @@ private <O extends ObjectType> Boolean executeScript(PrismProperty<Object> expre
scripting.evaluateExpression((ScriptingExpressionType) parsed, task, result);
result.recordSuccess();
result.addReturn("console", executionResult.getConsoleOutput());
LOGGER.info("Executed {} as part of post-initial import with output: {}", expression, executionResult.getConsoleOutput());
LOGGER.info("Executed a script in {} as part of post-initial import. Output is:\n{}", file.getName(), executionResult.getConsoleOutput());
return true;
} catch (Exception ex) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't execute script from file {}", ex, file.getName());
Expand Down Expand Up @@ -204,15 +194,16 @@ private File[] getPostInitialImportObjects() {

private File[] listFiles(File folder) {
File[] files = folder.listFiles();
File[] retFiles =new File[0];
for(File file: files){
if(file.isFile()){
retFiles = (File[])ArrayUtils.add(retFiles, file);
continue;
}
if(file.isDirectory()){

retFiles = (File[])ArrayUtils.addAll(retFiles, listFiles(file));
File[] retFiles = new File[0];
if (files != null) {
for (File file : files) {
if (file.isFile()) {
retFiles = (File[]) ArrayUtils.add(retFiles, file);
continue;
}
if (file.isDirectory()) {
retFiles = (File[]) ArrayUtils.addAll(retFiles, listFiles(file));
}
}
}
return retFiles;
Expand All @@ -231,5 +222,4 @@ private boolean checkDirectoryExistence(String dir) {
return false;
}
}

}
Expand Up @@ -100,7 +100,7 @@ public void test010ListConnectors() throws Exception {
result.computeStatus();
TestUtil.assertSuccess("getObject result", result);

assertEquals("Unexpected number of connectors", 11, connectors.size());
assertEquals("Unexpected number of connectors", 12, connectors.size());
for(PrismObject<ConnectorType> connector: connectors) {
display("Connector", connector);
ConnectorType connectorType = connector.asObjectable();
Expand Down
Expand Up @@ -79,7 +79,7 @@ public void test001Connectors() throws Exception {
IntegrationTestTools.assertConnectorSchemaSanity(conn, prismContext);
}

assertEquals("Unexpected number of connectors found", 9, connectors.size());
assertEquals("Unexpected number of connectors found", 10, connectors.size());
}

@Test
Expand All @@ -99,7 +99,7 @@ public void testListConnectors() throws Exception{
System.out.println("-----\n");
}

assertEquals("Unexpected number of connectors found", 9, connectors.size());
assertEquals("Unexpected number of connectors found", 10, connectors.size());
}

@Test
Expand Down
Expand Up @@ -136,6 +136,10 @@ public abstract class AbstractOpenDjTest extends AbstractProvisioningIntegration
protected static final String GROUP_CORSAIRS_OID = "70a1f3ee-4b5b-11e5-95d0-001e8c717e5b";
protected static final String GROUP_CORSAIRS_DN = "cn=corsairs,ou=groups,dc=example,dc=com";

protected static final File OU_SUPER_FILE = new File(TEST_DIR, "ou-super.xml");
protected static final String OU_SUPER_OID = "1d1e519e-0d22-11ea-8cdf-3f09f7f3a585";
protected static final String OU_SUPER_DN = "ou=Super,dc=example,dc=com";

protected static final String NON_EXISTENT_OID = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee";

public static final String RESOURCE_NS = "http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff";
Expand Down
Expand Up @@ -37,6 +37,7 @@

import org.apache.commons.lang.StringUtils;
import org.opends.server.types.Entry;
import org.opends.server.util.LDIFException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
Expand Down Expand Up @@ -2852,7 +2853,7 @@ public void test456AddGroupSpecialists() throws Exception {
OperationResult result = task.getResult();

ShadowType object = parseObjectType(GROUP_SPECIALISTS_FILE, ShadowType.class);
IntegrationTestTools.display("Adding object", object);
display("Adding object", object);

// WHEN
displayWhen(TEST_NAME);
Expand Down Expand Up @@ -3283,6 +3284,84 @@ public void test479ModifyAccountJackDescriptionJack() throws Exception {
assertShadows(25);
}

@Test
public void test480AddOuSuper() throws Exception {
final String TEST_NAME = "test480AddOuSuper";
displayTestTitle(TEST_NAME);

Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();

ShadowType object = parseObjectType(OU_SUPER_FILE, ShadowType.class);
display("Adding object", object);

// WHEN
displayWhen(TEST_NAME);
String addedObjectOid = provisioningService.addObject(object.asPrismObject(), null, null, task, result);

// THEN
displayThen(TEST_NAME);
assertEquals(OU_SUPER_OID, addedObjectOid);

ShadowType shadowType = getShadowRepo(OU_SUPER_OID).asObjectable();
PrismAsserts.assertEqualsPolyString("Wrong ICF name (repo)", OU_SUPER_DN, shadowType.getName());

PrismObject<ShadowType> provisioningShadow = provisioningService.getObject(ShadowType.class, OU_SUPER_OID,
null, taskManager.createTaskInstance(), result);
ShadowType provisioningShadowType = provisioningShadow.asObjectable();
assertEquals("Wrong ICF name (provisioning)", dnMatchingRule.normalize(OU_SUPER_DN),
dnMatchingRule.normalize(provisioningShadowType.getName().getOrig()));

String uid = ShadowUtil.getSingleStringAttributeValue(shadowType, getPrimaryIdentifierQName());
assertNotNull(uid);

Entry ldapEntry = openDJController.searchAndAssertByEntryUuid(uid);
display("LDAP ou", ldapEntry);
assertNotNull("No LDAP ou entry");
String groupDn = ldapEntry.getDN().toString();
assertEquals("Wrong ou DN", dnMatchingRule.normalize(OU_SUPER_DN), dnMatchingRule.normalize(groupDn));

assertShadows(26);
}

/**
* Try to delete ou=Super,dc=example,dc=com. But before doing that create a subobject:
* ou=sub,ou=Super,dc=example,dc=com. LDAP server should normally refuse to delete the Super OU
* because it is not empty. But we have configured use of "tree delete" control here.
* Therefore the delete should work.
*
* MID-5935
*/
@Test
public void test489DeleteOuSuperWithSub() throws Exception {
final String TEST_NAME = "test489DeleteOuSuperWithSub";
displayTestTitle(TEST_NAME);

Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();

createSubOrg();

// WHEN
displayWhen(TEST_NAME);
provisioningService.deleteObject(ShadowType.class, OU_SUPER_OID, null, null, task, result);

// THEN
displayThen(TEST_NAME);
assertSuccess(result);

assertNoRepoShadow(OU_SUPER_OID);
openDJController.assertNoEntry(OU_SUPER_DN);

assertShadows(25);
}

protected void createSubOrg() throws IOException, LDIFException {
openDJController.addEntry("dn: ou=sub,ou=Super,dc=example,dc=com\n"+
"objectClass: organizationalUnit\n"+
"ou: sub");
}

@Test
public void test701ConfiguredCapabilityNoRead() throws Exception{
final String TEST_NAME = "test701ConfiguredCapabilityNoRead";
Expand Down
Expand Up @@ -11,6 +11,9 @@

import java.io.File;

import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;

Expand All @@ -19,6 +22,7 @@
import com.evolveum.midpoint.util.DOMUtil;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import org.testng.annotations.Test;

/**
* Test for provisioning service implementation using embedded OpenDj instance.
Expand Down Expand Up @@ -73,4 +77,33 @@ protected void assertTimestamp(String attrName, Object timestampValue) {
assertTrue("Timestamp "+attrName+" does not end with Z: "+str, str.endsWith("Z"));
}

/**
* This resource has disabled "tree delete".
*/
@Test
@Override
public void test489DeleteOuSuperWithSub() throws Exception {
final String TEST_NAME = "test489DeleteOuSuperWithSub";
displayTestTitle(TEST_NAME);

Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();

createSubOrg();

try {
// WHEN
displayWhen(TEST_NAME);
provisioningService.deleteObject(ShadowType.class, OU_SUPER_OID, null, null, task, result);

assertNotReached();
} catch (IllegalArgumentException e) {
// expected
}

// THEN
displayThen(TEST_NAME);
assertFailure(result);
}

}

0 comments on commit 40092ad

Please sign in to comment.