Skip to content

Commit

Permalink
Add merging of additional connectors
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed May 6, 2022
1 parent 1e141fb commit 8f09023
Show file tree
Hide file tree
Showing 13 changed files with 612 additions and 201 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@
package com.evolveum.midpoint.schema.util;

import java.util.*;
import java.util.stream.Collectors;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.exception.ConfigurationException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import com.evolveum.midpoint.xml.ns._public.connector.icf_1.connector_schema_3.ConfigurationPropertiesType;
import com.evolveum.midpoint.xml.ns._public.connector.icf_1.connector_schema_3.ResultsHandlerConfigurationType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.*;

import org.apache.commons.collections4.CollectionUtils;
Expand All @@ -19,10 +25,6 @@
import org.jetbrains.annotations.Nullable;
import org.w3c.dom.Element;

import com.evolveum.midpoint.prism.PrismContainer;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.PrismReference;
import com.evolveum.midpoint.schema.CapabilityUtil;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
Expand All @@ -34,6 +36,9 @@
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.prism.xml.ns._public.types_3.SchemaDefinitionType;

import static com.evolveum.midpoint.schema.SchemaConstantsGenerated.ICF_C_RESULTS_HANDLER_CONFIGURATION;
import static com.evolveum.midpoint.schema.constants.SchemaConstants.ICF_CONFIGURATION_PROPERTIES;

/**
* Methods that would belong to the ResourceType class but cannot go there
* because of JAXB.
Expand Down Expand Up @@ -437,6 +442,69 @@ public static ResourceObjectTypeDefinitionType getResourceObjectTypeDefinitionTy
return null;
}

/**
* @throws ConfigurationException e.g. if the connectorName matches no configuration
*/
public static @Nullable PrismContainerValue<ConfigurationPropertiesType> getConfigurationProperties(
@NotNull ResourceType resource, @Nullable String connectorName) throws ConfigurationException {
ConnectorConfigurationType config = getConnectorConfiguration(resource, connectorName);
if (config == null) {
return null;
}
//noinspection unchecked
PrismContainer<ConfigurationPropertiesType> propertiesContainer =
config.asPrismContainerValue().findContainer(ICF_CONFIGURATION_PROPERTIES);
if (propertiesContainer == null || propertiesContainer.hasNoValues()) {
return null;
}
return propertiesContainer.getValue();
}

/**
* @throws ConfigurationException e.g. if the connectorName matches no configuration
*/
public static @Nullable ConnectorConfigurationType getConnectorConfiguration(
@NotNull ResourceType resource, @Nullable String connectorName) throws ConfigurationException {
if (connectorName == null) {
return resource.getConnectorConfiguration();
} else {
return getAdditionalConnectorSpec(resource, connectorName)
.getConnectorConfiguration();
}
}

/**
* @throws ConfigurationException e.g. if the connectorName matches no configuration
*/
public static @NotNull ConnectorInstanceSpecificationType getAdditionalConnectorSpec(
@NotNull ResourceType resource, @NotNull String name) throws ConfigurationException {
var matching = resource.getAdditionalConnector().stream()
.filter(s -> name.equals(s.getName()))
.collect(Collectors.toList());
return MiscUtil.extractSingletonRequired(
matching,
() -> new ConfigurationException("Multiple additional connectors with the name '" + name + "': " + matching),
() -> new ConfigurationException("No additional connector with the name '" + name + "'"));
}

/**
* @throws ConfigurationException e.g. if the connectorName matches no configuration
*/
public static @Nullable PrismContainerValue<ResultsHandlerConfigurationType> getResultsHandlerConfiguration(
@NotNull ResourceType resource, @Nullable String connectorName) throws ConfigurationException {
ConnectorConfigurationType config = getConnectorConfiguration(resource, connectorName);
if (config == null) {
return null;
}
//noinspection unchecked
PrismContainer<ResultsHandlerConfigurationType> handlerContainer =
config.asPrismContainerValue().findContainer(ICF_C_RESULTS_HANDLER_CONFIGURATION);
if (handlerContainer == null || handlerContainer.hasNoValues()) {
return null;
}
return handlerContainer.getValue();
}

public static PrismContainer<ConnectorConfigurationType> getConfigurationContainer(ResourceType resourceType) {
return getConfigurationContainer(resourceType.asPrismObject());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class ResourceExpansionOperation {
private static final Trace LOGGER = TraceManager.getTrace(ResourceExpansionOperation.class);

private static final List<ItemPath> PATHS_FOR_FIRST_PASS = List.of(
F_NAME, // because it's technically considered obligatory + for diagnostic purposes
F_CONNECTOR_REF,
F_SUPER,
ItemPath.create(F_ADDITIONAL_CONNECTOR, ConnectorInstanceSpecificationType.F_NAME),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -433,16 +433,20 @@ ConnectorSpec getConnectorSpec(
throws ConfigurationException {
String connectorName = additionalConnectorSpecBean.getName();
configCheck(StringUtils.isNotBlank(connectorName), "No connector name in additional connector in %s", resource);
configCheck(additionalConnectorSpecBean.getConnectorRef() != null,
"No connector reference in additional connector '%s' in %s", connectorName, resource);
String connectorOid = additionalConnectorSpecBean.getConnectorRef().getOid();
configCheck(StringUtils.isNotBlank(connectorOid),
"No connector OID in additional connector '%s' in %s", connectorName, resource);

// connector OID is not required here, as it may come from the super-resource
String connectorOid = getConnectorOid(additionalConnectorSpecBean);

//noinspection unchecked
PrismContainer<ConnectorConfigurationType> connectorConfiguration =
additionalConnectorSpecBean.asPrismContainerValue().findContainer(
ConnectorInstanceSpecificationType.F_CONNECTOR_CONFIGURATION);

return new ConnectorSpec(resource, connectorName, connectorOid, connectorConfiguration);
}

private String getConnectorOid(@NotNull ConnectorInstanceSpecificationType bean) {
ObjectReferenceType ref = bean.getConnectorRef();
return ref != null ? ref.getOid() : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@

package com.evolveum.midpoint.provisioning.impl.resources;

import static com.evolveum.midpoint.test.IntegrationTestTools.DUMMY_CONNECTOR_TYPE;
import static com.evolveum.midpoint.xml.ns._public.connector.icf_1.connector_schema_3.ResultsHandlerConfigurationType.*;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import com.evolveum.midpoint.prism.crypto.EncryptionException;
import com.evolveum.midpoint.test.IntegrationTestTools;
import com.evolveum.midpoint.prism.path.ItemName;

import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;

import org.testng.annotations.Test;

Expand All @@ -32,19 +39,36 @@ public class TestResourceTemplateMerge extends AbstractProvisioningIntegrationTe
TEST_DIR, "resource-template-basic.xml", "2d1bbd38-8292-4895-af07-15de1ae423ec");
private static final TestResource<ResourceType> RESOURCE_BASIC_1 = new TestResource<>(
TEST_DIR, "resource-basic-1.xml", "b6f77fb9-8bdf-42de-b7d4-639c77fa6805");
private static final TestResource<ResourceType> RESOURCE_BASIC_2 = new TestResource<>(
TEST_DIR, "resource-basic-2.xml", "969d0587-b049-4067-a749-2fe61d5fb2f6");

private static final TestResource<ResourceType> RESOURCE_TEMPLATE_ADDITIONAL_CONNECTORS = new TestResource<>(
TEST_DIR, "resource-template-additional-connectors.xml", "e17dfe38-727f-41b6-ab1c-9106c0bb046d");
private static final TestResource<ResourceType> RESOURCE_ADDITIONAL_CONNECTORS_1 = new TestResource<>(
TEST_DIR, "resource-additional-connectors-1.xml", "dcf805dc-afff-46c1-bf8c-876777ef4af5");

@Override
public void initSystem(Task initTask, OperationResult initResult) throws Exception {
super.initSystem(initTask, initResult);

initDummyResource(RESOURCE_TEMPLATE_BASIC, initResult);
initDummyResource(RESOURCE_TEMPLATE_BASIC, List.of(DUMMY_CONNECTOR_TYPE), initResult);
repoAdd(RESOURCE_BASIC_1, initResult); // No connectorRef is here, so basic add is OK
repoAdd(RESOURCE_BASIC_2, initResult); // No connectorRef is here, so basic add is OK

initDummyResource(
RESOURCE_TEMPLATE_ADDITIONAL_CONNECTORS,
List.of(DUMMY_CONNECTOR_TYPE, DUMMY_CONNECTOR_TYPE, DUMMY_CONNECTOR_TYPE),
initResult);
initDummyResource(
RESOURCE_ADDITIONAL_CONNECTORS_1,
Arrays.asList(null, null, DUMMY_CONNECTOR_TYPE),
initResult); // No connectorRef is here, so basic add is OK
}

/** Provides connector OID externally. */
private void initDummyResource(TestResource<ResourceType> resource, OperationResult result)
private void initDummyResource(TestResource<ResourceType> resource, List<String> connectorTypes, OperationResult result)
throws CommonException, EncryptionException, IOException {
addResourceFromFile(resource.file, IntegrationTestTools.DUMMY_CONNECTOR_TYPE, result);
addResourceFromFile(resource.file, connectorTypes, false, result);
resource.reload(result);
}

Expand All @@ -59,16 +83,124 @@ public void test100Basic1() throws CommonException {
expansionOperation.execute(result);

then("expanded version is OK");
// @formatter:off
assertResource(expansionOperation.getExpandedResource(), "after")
.assertName("Basic 1")
.assertNotAbstract();
.assertNotAbstract()
.configurationProperties()
.assertSize(4)
.assertAllItemsHaveCompleteDefinition()
.assertPropertyEquals(new ItemName("supportValidity"), false) // overridden
.assertPropertyEquals(new ItemName("instanceId"), "basic") // from template
.assertPropertyEquals(new ItemName("uselessString"), "Shiver me timbers!") // from template
.assertPropertyEquals(new ItemName("uselessGuardedString"),
new ProtectedStringType().clearValue("Dead men tell no tales")) // from template
.end()
.resultsHandlerConfiguration()
.assertSize(4)
.assertAllItemsHaveCompleteDefinition()
.assertPropertyEquals(F_FILTERED_RESULTS_HANDLER_IN_VALIDATION_MODE, true) // added by basic-1
.assertPropertyEquals(F_ENABLE_FILTERED_RESULTS_HANDLER, false) // from template
.assertPropertyEquals(F_ENABLE_ATTRIBUTES_TO_GET_SEARCH_RESULTS_HANDLER, false) // from template
.assertPropertyEquals(F_ENABLE_NORMALIZING_RESULTS_HANDLER, false) // from template
.end()
.assertConnectorRef(RESOURCE_TEMPLATE_BASIC.getObjectable().getConnectorRef());
// @formatter:on

and("ancestors are OK");
assertThat(expansionOperation.getAncestorsOids())
.as("ancestors OIDs")
.containsExactly(RESOURCE_TEMPLATE_BASIC.oid);
}

@Test
public void test110Basic2() throws CommonException {
OperationResult result = getTestOperationResult();

when("basic2 is expanded");
ResourceExpansionOperation expansionOperation = new ResourceExpansionOperation(
RESOURCE_BASIC_2.getObjectable().clone(),
beans);
expansionOperation.execute(result);

then("expanded version is OK");
// @formatter:off
assertResource(expansionOperation.getExpandedResource(), "after")
.assertName("Basic 2")
.assertNotAbstract()
.configurationProperties()
.assertSize(4)
.assertAllItemsHaveCompleteDefinition()
.assertPropertyEquals(new ItemName("supportValidity"), false) // overridden (Basic 1)
.assertPropertyEquals(new ItemName("instanceId"), "basic") // from template
.assertPropertyEquals(new ItemName("uselessString"), "False!") // overridden (Basic 2)
.assertPropertyEquals(new ItemName("uselessGuardedString"),
new ProtectedStringType().clearValue("Dead men tell no tales")) // from template
.end()
.resultsHandlerConfiguration()
.assertSize(4)
.assertAllItemsHaveCompleteDefinition()
.assertPropertyEquals(F_FILTERED_RESULTS_HANDLER_IN_VALIDATION_MODE, true) // added by basic-1
.assertPropertyEquals(F_ENABLE_FILTERED_RESULTS_HANDLER, false) // from template
.assertPropertyEquals(F_ENABLE_ATTRIBUTES_TO_GET_SEARCH_RESULTS_HANDLER, false) // from template
.assertPropertyEquals(F_ENABLE_NORMALIZING_RESULTS_HANDLER, false) // from template
.end()
.assertConnectorRef(RESOURCE_TEMPLATE_BASIC.getObjectable().getConnectorRef());
// @formatter:on

and("ancestors are OK");
assertThat(expansionOperation.getAncestorsOids())
.as("ancestors OIDs")
.containsExactlyInAnyOrder(RESOURCE_TEMPLATE_BASIC.oid, RESOURCE_BASIC_1.oid);
}

@Test
public void test120MultipleConnectors() throws CommonException {
OperationResult result = getTestOperationResult();

when("additional-connectors-1 is expanded");
ResourceExpansionOperation expansionOperation = new ResourceExpansionOperation(
RESOURCE_ADDITIONAL_CONNECTORS_1.getObjectable().clone(),
beans);
expansionOperation.execute(result);

then("expanded version is OK");
// @formatter:off
assertResource(expansionOperation.getExpandedResource(), "after")
.assertName("With additional connectors 1")
.assertNotAbstract()
.configurationProperties()
.assertSize(2)
.assertAllItemsHaveCompleteDefinition()
.assertPropertyEquals(new ItemName("instanceId"), "main") // from template
.assertPropertyEquals(new ItemName("supportValidity"), true) // from specific
.end()
.assertConnectorRef(RESOURCE_TEMPLATE_ADDITIONAL_CONNECTORS.getObjectable().getConnectorRef())
.assertAdditionalConnectorsCount(3)
.configurationProperties("first")
.assertSize(2)
.assertAllItemsHaveCompleteDefinition()
.assertPropertyEquals(new ItemName("instanceId"), "first") // from template
.assertPropertyEquals(new ItemName("uselessString"), "merged") // from specific
.end()
.configurationProperties("second") // from template
.assertSize(1)
.assertAllItemsHaveCompleteDefinition()
.assertPropertyEquals(new ItemName("instanceId"), "second")
.end()
.configurationProperties("third") // from specific
.assertSize(1)
.assertAllItemsHaveCompleteDefinition()
.assertPropertyEquals(new ItemName("instanceId"), "third")
.end();
// @formatter:on

and("ancestors are OK");
assertThat(expansionOperation.getAncestorsOids())
.as("ancestors OIDs")
.containsExactly(RESOURCE_TEMPLATE_ADDITIONAL_CONNECTORS.oid);
}

private ResourceType expand(TestResource<ResourceType> raw, OperationResult result) throws CommonException {
ResourceExpansionOperation expansionOperation = new ResourceExpansionOperation(
raw.getObjectable().clone(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2010-2018 Evolveum and contributors
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->

<resource oid="dcf805dc-afff-46c1-bf8c-876777ef4af5"
xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.icf.dummy/com.evolveum.icf.dummy.connector.DummyConnector"
xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
<name>With additional connectors 1</name>
<super>
<resourceRef oid="e17dfe38-727f-41b6-ab1c-9106c0bb046d"/>
</super>
<connectorConfiguration >
<icfc:configurationProperties>
<!-- adding new value -->
<icfi:supportValidity>true</icfi:supportValidity>
</icfc:configurationProperties>
</connectorConfiguration>
<additionalConnector>
<!-- merged with the configuration from the template -->
<name>first</name>
<connectorConfiguration>
<icfc:configurationProperties>
<icfi:uselessString>merged</icfi:uselessString>
</icfc:configurationProperties>
</connectorConfiguration>
</additionalConnector>
<additionalConnector>
<!-- our own-->
<name>third</name>
<connectorRef oid="provided-by-test-code" type="ConnectorType"/>
<connectorConfiguration>
<icfc:configurationProperties>
<icfi:instanceId>third</icfi:instanceId>
</icfc:configurationProperties>
</connectorConfiguration>
</additionalConnector>
</resource>
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@
-->

<resource oid="b6f77fb9-8bdf-42de-b7d4-639c77fa6805"
xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3">
xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.icf.dummy/com.evolveum.icf.dummy.connector.DummyConnector"
xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
<name>Basic 1</name>
<super>
<resourceRef oid="2d1bbd38-8292-4895-af07-15de1ae423ec"/>
</super>
<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.icf.dummy/com.evolveum.icf.dummy.connector.DummyConnector"
xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">

<connectorConfiguration >
<icfc:configurationProperties>
<!-- overriding existing value -->
<icfi:supportValidity>false</icfi:supportValidity>
</icfc:configurationProperties>

<icfc:resultsHandlerConfiguration>
<!-- adding new item -->
<icfc:filteredResultsHandlerInValidationMode>true</icfc:filteredResultsHandlerInValidationMode>
Expand Down

0 comments on commit 8f09023

Please sign in to comment.