Create Operation

The create operation interface enables the connector to create objects on the target system. The operation includes one method (create()). The method takes an ObjectClass, and any provided attributes, and creates the object and its UID. The connector must return the UID so that the caller can refer to the created object.

The connector should make a best effort to create the object, and should throw an informative RuntimeException, indicating to the caller why the operation could not be completed. Defaults can be used for any required attributes, as long as the defaults are documented.

The UID is never passed in with the attribute set for this method. If the resource supports a mutable UID, you can create a resource-specific attribute for the ID, such as unix_uid.

If the create operation is only partially successful, the connector should attempt to roll back the partial change. If the target system does not allow this, the connector should report the partial success of the create operation and throw a RetryableException. For example:

public static RetryableException wrap(final String message, final Uid uid) {
    return new RetryableException(message, new AlreadyExistsException().initUid(Assertions
    .nullChecked(uid, "Uid")));
}

Use the ICF Create Operation

The following exceptions are thrown by the Create API operation:

  • IllegalArgumentException - if ObjectClass is missing, or if elements of the set produce duplicate values of Attribute#getName()

  • NullPointerException - if the createAttributes parameter is null

  • RuntimeException - if the Connector SPI throws a native exception

Consumption of the Create Operation, at the API Level
@Test
public void createTest() {
    logger.info("Running Create Test");
    final ConnectorFacade facade = createConnectorFacade(BasicConnector.class, null);
    final OperationOptionsBuilder builder = new OperationOptionsBuilder();
    Set<Attribute> createAttributes = new HashSet<Attribute>();
    createAttributes.add(new Name("Foo"));
    createAttributes.add(AttributeBuilder.buildPassword("Password".toCharArray()));
    createAttributes.add(AttributeBuilder.buildEnabled(true));
    Uid uid = facade.create(ObjectClass.ACCOUNT, createAttributes, builder.build());
    Assert.assertEquals(uid.getUidValue(), "foo");
}

Implement the Create Operation

The SPI provides the following detailed exceptions:

  • UnsupportedOperationException - the create operation is not supported for the specified object class

  • InvalidAttributeValueException - a required attribute is missing, an attribute is present that cannot be created, or a provided attribute has an invalid value

  • AlreadyExistsException - an object with the specified Name already exits on the target system

  • PermissionDeniedException - the target resource will not allow the connector to perform the specified operation

  • ConnectorIOException, ConnectionBrokenException, ConnectionFailedException - a problem as occurred with the connection

  • RuntimeException - thrown if anything else goes wrong. You should try to throw a native exception in this case.

Implementation of the Create Operation, at the SPI Level
public Uid create(final ObjectClass objectClass, final Set<Attribute> createAttributes,
        final OperationOptions options) {
    if (ObjectClass.ACCOUNT.equals(objectClass) || ObjectClass.GROUP.equals(objectClass)) {
        Name name = AttributeUtil.getNameFromAttributes(createAttributes);
        if (name != null) {
            // do real create here
            return new Uid(AttributeUtil.getStringValue(name).toLowerCase());
        } else {
            throw new InvalidAttributeValueException("Name attribute is required");
        }
    } else {
        logger.warn("Delete of type {0} is not supported", configuration.getConnectorMessages()
                .format(objectClass.getDisplayNameKey(), objectClass.getObjectClassValue()));
        throw new UnsupportedOperationException("Delete of type"
                + objectClass.getObjectClassValue() + " is not supported");
    }
}