Search in sources :

Example 1 with MutablePrismSchema

use of com.evolveum.midpoint.prism.schema.MutablePrismSchema in project midpoint by Evolveum.

the class ConnectorFactoryBuiltinImpl method generateConnectorConfigurationSchema.

private PrismSchema generateConnectorConfigurationSchema(ConnectorStruct struct) {
    Class<? extends ConnectorInstance> connectorClass = struct.connectorClass;
    PropertyDescriptor connectorConfigurationProp = UcfUtil.findAnnotatedProperty(connectorClass, ManagedConnectorConfiguration.class);
    MutablePrismSchema connectorSchema = prismContext.schemaFactory().createPrismSchema(struct.connectorObject.getNamespace());
    // Create configuration type - the type used by the "configuration" element
    MutablePrismContainerDefinition<?> configurationContainerDef = connectorSchema.createContainerDefinition(ResourceType.F_CONNECTOR_CONFIGURATION.getLocalPart(), SchemaConstants.CONNECTOR_SCHEMA_CONFIGURATION_TYPE_LOCAL_NAME);
    Class<?> configurationClass = connectorConfigurationProp.getPropertyType();
    BeanWrapper configurationClassBean = new BeanWrapperImpl(configurationClass);
    for (PropertyDescriptor prop : configurationClassBean.getPropertyDescriptors()) {
        if (UcfUtil.hasAnnotation(prop, ConfigurationItem.class)) {
            ItemDefinition<?> itemDef = createConfigurationItemDefinition(configurationContainerDef, prop);
            LOGGER.trace("Configuration item definition for {}: {}", prop.getName(), itemDef);
        }
    }
    return connectorSchema;
}
Also used : BeanWrapper(org.springframework.beans.BeanWrapper) PropertyDescriptor(java.beans.PropertyDescriptor) BeanWrapperImpl(org.springframework.beans.BeanWrapperImpl) MutablePrismSchema(com.evolveum.midpoint.prism.schema.MutablePrismSchema)

Example 2 with MutablePrismSchema

use of com.evolveum.midpoint.prism.schema.MutablePrismSchema in project midpoint by Evolveum.

the class ResourceManager method applyDefinition.

public void applyDefinition(ObjectDelta<ResourceType> delta, ResourceType resourceWhenNoOid, GetOperationOptions options, Task task, OperationResult objectResult) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException {
    if (delta.isAdd()) {
        PrismObject<ResourceType> resource = delta.getObjectToAdd();
        applyConnectorSchemasToResource(resource, task, objectResult);
        return;
    } else if (delta.isModify()) {
    // Go on
    } else {
        return;
    }
    if (delta.hasCompleteDefinition()) {
        // nothing to do, all modifications has definitions..just aplly this deltas..
        return;
    }
    PrismObject<ResourceType> resource;
    String resourceOid = delta.getOid();
    if (resourceOid == null) {
        Validate.notNull(resourceWhenNoOid, "Resource oid not specified in the object delta, and resource is not specified as well. Could not apply definition.");
        resource = resourceWhenNoOid.asPrismObject();
    } else {
        resource = getResource(resourceOid, options, task, objectResult);
    }
    ResourceType resourceType = resource.asObjectable();
    // ResourceType resourceType = completeResource(resource.asObjectable(), null, objectResult);
    // TODO TODO TODO FIXME FIXME FIXME copied from ObjectImprted..union this two cases
    PrismContainer<ConnectorConfigurationType> configurationContainer = ResourceTypeUtil.getConfigurationContainer(resourceType);
    if (configurationContainer == null || configurationContainer.isEmpty()) {
        // Nothing to check
        objectResult.recordWarning("The resource has no configuration");
        return;
    }
    // Check the resource configuration. The schema is in connector, so fetch the connector first
    String connectorOid = resourceType.getConnectorRef().getOid();
    if (StringUtils.isBlank(connectorOid)) {
        objectResult.recordFatalError("The connector reference (connectorRef) is null or empty");
        return;
    }
    // ItemDelta.findItemDelta(delta.getModifications(), ResourceType.F_SCHEMA, ContainerDelta.class) == null ||
    ReferenceDelta connectorRefDelta = ItemDeltaCollectionsUtil.findReferenceModification(delta.getModifications(), ResourceType.F_CONNECTOR_REF);
    if (connectorRefDelta != null) {
        Item<PrismReferenceValue, PrismReferenceDefinition> connectorRefNew = connectorRefDelta.getItemNewMatchingPath(null);
        if (connectorRefNew.getValues().size() == 1) {
            PrismReferenceValue connectorRefValue = connectorRefNew.getValues().iterator().next();
            if (connectorRefValue.getOid() != null && !connectorOid.equals(connectorRefValue.getOid())) {
                connectorOid = connectorRefValue.getOid();
            }
        }
    }
    PrismObject<ConnectorType> connector;
    ConnectorType connectorType;
    try {
        connector = repositoryService.getObject(ConnectorType.class, connectorOid, null, objectResult);
        connectorType = connector.asObjectable();
    } catch (ObjectNotFoundException e) {
        // No connector, no fun. We can't check the schema. But this is referential integrity problem.
        // Mark the error ... there is nothing more to do
        objectResult.recordFatalError("Connector (OID:" + connectorOid + ") referenced from the resource is not in the repository", e);
        return;
    } catch (SchemaException e) {
        // Probably a malformed connector. To be kind of robust, lets allow the import.
        // Mark the error ... there is nothing more to do
        objectResult.recordPartialError("Connector (OID:" + connectorOid + ") referenced from the resource has schema problems: " + e.getMessage(), e);
        LOGGER.error("Connector (OID:{}) referenced from the imported resource \"{}\" has schema problems: {}-{}", connectorOid, resourceType.getName(), e.getMessage(), e);
        return;
    }
    Element connectorSchemaElement = ConnectorTypeUtil.getConnectorXsdSchema(connector);
    MutablePrismSchema connectorSchema;
    if (connectorSchemaElement == null) {
        // No schema to validate with
        return;
    }
    try {
        connectorSchema = prismContext.schemaFactory().createPrismSchema(DOMUtil.getSchemaTargetNamespace(connectorSchemaElement));
        connectorSchema.parseThis(connectorSchemaElement, true, "schema for " + connector, prismContext);
    } catch (SchemaException e) {
        objectResult.recordFatalError("Error parsing connector schema for " + connector + ": " + e.getMessage(), e);
        return;
    }
    QName configContainerQName = new QName(connectorType.getNamespace(), ResourceType.F_CONNECTOR_CONFIGURATION.getLocalPart());
    PrismContainerDefinition<ConnectorConfigurationType> configContainerDef = connectorSchema.findContainerDefinitionByElementName(configContainerQName);
    if (configContainerDef == null) {
        objectResult.recordFatalError("Definition of configuration container " + configContainerQName + " not found in the schema of of " + connector);
        return;
    }
    try {
        configurationContainer.applyDefinition(configContainerDef);
    } catch (SchemaException e) {
        objectResult.recordFatalError("Configuration error in " + resource + ": " + e.getMessage(), e);
        return;
    }
    PrismContainer configContainer = resourceType.asPrismObject().findContainer(ResourceType.F_CONNECTOR_CONFIGURATION);
    // noinspection unchecked
    configContainer.applyDefinition(configContainerDef);
    for (ItemDelta<?, ?> itemDelta : delta.getModifications()) {
        applyItemDefinition(itemDelta, configContainerDef, objectResult);
    }
}
Also used : QName(javax.xml.namespace.QName) Element(org.w3c.dom.Element) MutablePrismSchema(com.evolveum.midpoint.prism.schema.MutablePrismSchema)

Example 3 with MutablePrismSchema

use of com.evolveum.midpoint.prism.schema.MutablePrismSchema in project midpoint by Evolveum.

the class ObjectImporter method validateWithDynamicSchemas.

private <T extends ObjectType> void validateWithDynamicSchemas(PrismObject<T> object, RepositoryService repository, OperationResult objectResult) {
    // TODO: check extension schema (later)
    OperationResult result = objectResult.createSubresult(OPERATION_VALIDATE_DYN_SCHEMA);
    if (object.canRepresent(ConnectorType.class)) {
        ConnectorType connector = (ConnectorType) object.asObjectable();
        checkSchema(connector.getSchema(), "connector", result);
        result.computeStatus("Connector schema error");
        result.recordSuccessIfUnknown();
    } else if (object.canRepresent(ResourceType.class)) {
        // Only two object types have XML snippets that conform to the dynamic schema
        // noinspection unchecked
        PrismObject<ResourceType> resource = (PrismObject<ResourceType>) object;
        ResourceType resourceType = resource.asObjectable();
        PrismContainer<ConnectorConfigurationType> configurationContainer = ResourceTypeUtil.getConfigurationContainer(resource);
        if (configurationContainer == null || configurationContainer.isEmpty()) {
            // Nothing to check
            result.recordWarning("The resource has no configuration");
            return;
        }
        // Check the resource configuration. The schema is in connector, so fetch the connector first
        String connectorOid = resourceType.getConnectorRef().getOid();
        if (StringUtils.isBlank(connectorOid)) {
            result.recordFatalError("The connector reference (connectorRef) is null or empty");
            return;
        }
        PrismObject<ConnectorType> connector;
        ConnectorType connectorType;
        try {
            connector = repository.getObject(ConnectorType.class, connectorOid, null, result);
            connectorType = connector.asObjectable();
        } catch (ObjectNotFoundException e) {
            // No connector, no fun. We can't check the schema. But this is referential integrity problem.
            // Mark the error ... there is nothing more to do
            result.recordFatalError("Connector (OID:" + connectorOid + ") referenced from the resource is not in the repository", e);
            return;
        } catch (SchemaException e) {
            // Probably a malformed connector. To be kind of robust, lets allow the import.
            // Mark the error ... there is nothing more to do
            result.recordPartialError("Connector (OID:" + connectorOid + ") referenced from the resource has schema problems: " + e.getMessage(), e);
            LOGGER.error("Connector (OID:{}) referenced from the imported resource \"{}\" has schema problems: {}", connectorOid, resourceType.getName(), e.getMessage(), e);
            return;
        }
        Element connectorSchemaElement = ConnectorTypeUtil.getConnectorXsdSchema(connector);
        MutablePrismSchema connectorSchema;
        if (connectorSchemaElement == null) {
            // No schema to validate with
            result.recordSuccessIfUnknown();
            return;
        }
        try {
            connectorSchema = prismContext.schemaFactory().createPrismSchema(DOMUtil.getSchemaTargetNamespace(connectorSchemaElement));
            connectorSchema.parseThis(connectorSchemaElement, true, "schema for " + connector, prismContext);
        } catch (SchemaException e) {
            result.recordFatalError("Error parsing connector schema for " + connector + ": " + e.getMessage(), e);
            return;
        }
        QName configContainerQName = new QName(connectorType.getNamespace(), ResourceType.F_CONNECTOR_CONFIGURATION.getLocalPart());
        PrismContainerDefinition<ConnectorConfigurationType> configContainerDef = connectorSchema.findContainerDefinitionByElementName(configContainerQName);
        if (configContainerDef == null) {
            result.recordFatalError("Definition of configuration container " + configContainerQName + " not found in the schema of of " + connector);
            return;
        }
        try {
            configurationContainer.applyDefinition(configContainerDef);
        } catch (SchemaException e) {
            result.recordFatalError("Configuration error in " + resource + ": " + e.getMessage(), e);
            return;
        }
        // now we check for raw data - their presence means e.g. that there is a connector property that is unknown in connector schema (applyDefinition does not scream in such a case!)
        try {
            // require definitions and prohibit raw
            configurationContainer.checkConsistence(true, true, ConsistencyCheckScope.THOROUGH);
        } catch (IllegalStateException e) {
            // TODO do this error checking and reporting in a cleaner and more user-friendly way
            result.recordFatalError("Configuration error in " + resource + " (probably incorrect connector property, see the following error): " + e.getMessage(), e);
            return;
        }
        // Also check integrity of the resource schema
        checkSchema(resourceType.getSchema(), "resource", result);
        result.computeStatus("Dynamic schema error");
    } else if (object.canRepresent(ShadowType.class)) {
    // TODO
    // objectResult.computeStatus("Dynamic schema error");
    }
    result.recordSuccessIfUnknown();
}
Also used : QName(javax.xml.namespace.QName) Element(org.w3c.dom.Element) MutablePrismSchema(com.evolveum.midpoint.prism.schema.MutablePrismSchema) OperationResult(com.evolveum.midpoint.schema.result.OperationResult)

Example 4 with MutablePrismSchema

use of com.evolveum.midpoint.prism.schema.MutablePrismSchema in project midpoint by Evolveum.

the class UcfUtil method getConnectorSchema.

public static PrismSchema getConnectorSchema(ConnectorType connectorType, PrismContext prismContext) throws SchemaException {
    XmlSchemaType xmlSchema = connectorType.getSchema();
    if (xmlSchema == null) {
        return null;
    }
    Element xsdElement = ObjectTypeUtil.findXsdElement(xmlSchema);
    if (xsdElement == null) {
        return null;
    }
    MutablePrismSchema connectorSchema = prismContext.schemaFactory().createPrismSchema(DOMUtil.getSchemaTargetNamespace(xsdElement));
    connectorSchema.parseThis(xsdElement, true, connectorType.toString(), prismContext);
    return connectorSchema;
}
Also used : Element(org.w3c.dom.Element) MutablePrismSchema(com.evolveum.midpoint.prism.schema.MutablePrismSchema) XmlSchemaType(com.evolveum.midpoint.xml.ns._public.common.common_3.XmlSchemaType)

Example 5 with MutablePrismSchema

use of com.evolveum.midpoint.prism.schema.MutablePrismSchema in project midpoint by Evolveum.

the class ConnectorFactoryConnIdImpl method generateConnectorConfigurationSchema.

private PrismSchema generateConnectorConfigurationSchema(ConnectorInfo cinfo, ConnectorType connectorType) {
    LOGGER.trace("Generating configuration schema for {}", this);
    APIConfiguration defaultAPIConfiguration = cinfo.createDefaultAPIConfiguration();
    ConfigurationProperties icfConfigurationProperties = defaultAPIConfiguration.getConfigurationProperties();
    if (icfConfigurationProperties == null || icfConfigurationProperties.getPropertyNames() == null || icfConfigurationProperties.getPropertyNames().isEmpty()) {
        LOGGER.debug("No configuration schema for {}", this);
        return null;
    }
    MutablePrismSchema connectorSchema = prismContext.schemaFactory().createPrismSchema(connectorType.getNamespace());
    // Create configuration type - the type used by the "configuration"
    // element
    MutablePrismContainerDefinition<?> configurationContainerDef = connectorSchema.createContainerDefinition(ResourceType.F_CONNECTOR_CONFIGURATION.getLocalPart(), SchemaConstants.CONNECTOR_SCHEMA_CONFIGURATION_TYPE_LOCAL_NAME);
    // element with "ConfigurationPropertiesType" - the dynamic part of
    // configuration schema
    ComplexTypeDefinition configPropertiesTypeDef = connectorSchema.createComplexTypeDefinition(new QName(connectorType.getNamespace(), ConnectorFactoryConnIdImpl.CONNECTOR_SCHEMA_CONFIGURATION_PROPERTIES_TYPE_LOCAL_NAME));
    // Create definition of "configurationProperties" type
    // (CONNECTOR_SCHEMA_CONFIGURATION_PROPERTIES_TYPE_LOCAL_NAME)
    int displayOrder = 1;
    for (String icfPropertyName : icfConfigurationProperties.getPropertyNames()) {
        ConfigurationProperty icfProperty = icfConfigurationProperties.getProperty(icfPropertyName);
        QName propXsdType = ConnIdCapabilitiesAndSchemaParser.connIdTypeToXsdType(icfProperty.getType(), icfProperty.isConfidential());
        LOGGER.trace("{}: Mapping ICF config schema property {} from {} to {}", this, icfPropertyName, icfProperty.getType(), propXsdType);
        MutablePrismPropertyDefinition<?> propertyDefinition = configPropertiesTypeDef.toMutable().createPropertyDefinition(icfPropertyName, propXsdType);
        propertyDefinition.setDisplayName(icfProperty.getDisplayName(null));
        propertyDefinition.setHelp(icfProperty.getHelpMessage(null));
        if (ConnIdCapabilitiesAndSchemaParser.isMultivaluedType(icfProperty.getType())) {
            propertyDefinition.setMaxOccurs(-1);
        } else {
            propertyDefinition.setMaxOccurs(1);
        }
        if (icfProperty.isRequired() && icfProperty.getValue() == null) {
            // If ICF says that the property is required it may not be in fact really required if it also has a default value
            propertyDefinition.setMinOccurs(1);
        } else {
            propertyDefinition.setMinOccurs(0);
        }
        propertyDefinition.setDisplayOrder(displayOrder);
        displayOrder++;
    }
    // Create common ICF configuration property containers as a references
    // to a static schema
    configurationContainerDef.createContainerDefinition(ConnectorFactoryConnIdImpl.CONNECTOR_SCHEMA_CONNECTOR_POOL_CONFIGURATION_ELEMENT, ConnectorFactoryConnIdImpl.CONNECTOR_SCHEMA_CONNECTOR_POOL_CONFIGURATION_TYPE, 0, 1);
    configurationContainerDef.createPropertyDefinition(ConnectorFactoryConnIdImpl.CONNECTOR_SCHEMA_PRODUCER_BUFFER_SIZE_ELEMENT, ConnectorFactoryConnIdImpl.CONNECTOR_SCHEMA_PRODUCER_BUFFER_SIZE_TYPE, 0, 1);
    configurationContainerDef.createContainerDefinition(ConnectorFactoryConnIdImpl.CONNECTOR_SCHEMA_TIMEOUTS_ELEMENT, ConnectorFactoryConnIdImpl.CONNECTOR_SCHEMA_TIMEOUTS_TYPE, 0, 1);
    configurationContainerDef.createContainerDefinition(ConnectorFactoryConnIdImpl.CONNECTOR_SCHEMA_RESULTS_HANDLER_CONFIGURATION_ELEMENT, ConnectorFactoryConnIdImpl.CONNECTOR_SCHEMA_RESULTS_HANDLER_CONFIGURATION_TYPE, 0, 1);
    configurationContainerDef.createPropertyDefinition(ConnectorFactoryConnIdImpl.CONNECTOR_SCHEMA_LEGACY_SCHEMA_ELEMENT, ConnectorFactoryConnIdImpl.CONNECTOR_SCHEMA_LEGACY_SCHEMA_TYPE, 0, 1);
    // No need to create definition of "configuration" element.
    // midPoint will look for this element, but it will be generated as part
    // of the PropertyContainer serialization to schema
    configurationContainerDef.createContainerDefinition(SchemaConstants.CONNECTOR_SCHEMA_CONFIGURATION_PROPERTIES_ELEMENT_QNAME, configPropertiesTypeDef, 1, 1);
    LOGGER.debug("Generated configuration schema for {}: {} definitions", this, connectorSchema.getDefinitions().size());
    return connectorSchema;
}
Also used : QName(javax.xml.namespace.QName) MutablePrismSchema(com.evolveum.midpoint.prism.schema.MutablePrismSchema) GuardedString(org.identityconnectors.common.security.GuardedString)

Aggregations

MutablePrismSchema (com.evolveum.midpoint.prism.schema.MutablePrismSchema)5 QName (javax.xml.namespace.QName)3 Element (org.w3c.dom.Element)3 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)1 XmlSchemaType (com.evolveum.midpoint.xml.ns._public.common.common_3.XmlSchemaType)1 PropertyDescriptor (java.beans.PropertyDescriptor)1 GuardedString (org.identityconnectors.common.security.GuardedString)1 BeanWrapper (org.springframework.beans.BeanWrapper)1 BeanWrapperImpl (org.springframework.beans.BeanWrapperImpl)1