Update Operation

If your connector will allow an authorized caller to update (modify or replace) objects on the target system, you must implement either the update operation, or the Update Attribute Values Operation. At the API level, update operation calls either the UpdateOp or the UpdateAttributeValuesOp, depending on what you have implemented.

The update operation is somewhat simpler to implement than the Update Attribute Values Operation, because the update attribute values operation must handle any type of update that the caller might specify. However a true implementation of the update attribute values operation offers better performance and atomicity semantics.

Use the ICF Update Operation

At the API level, the update operation returns an UnknownUidException if the UID does not exist on the target system resource and if the connector does not implement the Update Attribute Values Operation interface.

Consumption of the Update Operation at the API Level
@Test
public void updateTest() {
    logger.info("Running Update Test");
    final ConnectorFacade facade = createConnectorFacade(BasicConnector.class, null);
    final OperationOptionsBuilder builder = new OperationOptionsBuilder();
    Set<Attribute> updateAttributes = new HashSet<Attribute>();
    updateAttributes.add(new Name("Foo"));

    Uid uid = facade.update(ObjectClass.ACCOUNT, new Uid("Foo"), updateAttributes, builder
                  .build());
    Assert.assertEquals(uid.getUidValue(), "foo");
}

Implement the Update Operation

At the SPI level, the update operation returns an UnknownUidException if the UID does not exist on the target system.

Implementation of the Update Operation at the SPI Level
public Uid update(ObjectClass objectClass, Uid uid, Set<Attribute> replaceAttributes,
        OperationOptions options) {
    AttributesAccessor attributesAccessor = new AttributesAccessor(replaceAttributes);
    Name newName = attributesAccessor.getName();
    Uid uidAfterUpdate = uid;
    if (newName != null) {
        logger.info("Rename the object {0}:{1} to {2}", objectClass.getObjectClassValue(), uid
                .getUidValue(), newName.getNameValue());
        uidAfterUpdate = new Uid(newName.getNameValue().toLowerCase());
    }

    if (ObjectClass.ACCOUNT.equals(objectClass)) {

    } else if (ObjectClass.GROUP.is(objectClass.getObjectClassValue())) {
        if (attributesAccessor.hasAttribute("members")) {
            throw new InvalidAttributeValueException(
                    "Requested to update a read only attribute");
        }
    } else {
        logger.warn("Update of type {0} is not supported", configuration.getConnectorMessages()
                .format(objectClass.getDisplayNameKey(), objectClass.getObjectClassValue()));
        throw new UnsupportedOperationException("Update of type"
                + objectClass.getObjectClassValue() + " is not supported");
    }
    return uidAfterUpdate;
}

Approaches for Deleting Attributes and Attribute Values

If the target resource to which you are connecting supports the removal of attributes, you can implement the removal in several ways. All the samples in this document assume the following syntax rules for deleting attributes or removing their values.

Update Syntax rule Query filter

Set an empty attribute value

[""] (application sends an attribute value that is a list containing one empty string)

equal=""

Set an attribute value to null

[] (application sends an attribute value that is an empty list)

ispresent search returns 1

Removing an attribute

null (application sends an attribute value that is null

ispresent search returns 1