diff --git a/connector-amqp-import/README b/connector-amqp-import/README new file mode 100644 index 0000000..354c70d --- /dev/null +++ b/connector-amqp-import/README @@ -0,0 +1,47 @@ +# AMQP Import Connector for midPoint + +This is a proof of concept for integrating AMQP messages +into midPoint as a source for registry entries. Currently +it implements a very minimal sample of the TIER minimal +registry schema published in: + +* https://gist.github.com/geszes/b63b5c3dedff2a2f702c6fd54555b9cc + +Currently it is hard coded for a demonstration of importing +a minor sample of the schema such as: + +{ + "id": "EMPP00010", + "names": [ + { + "givenName": "Ethan", + "familyName": "Kromhout", + "formatted": "Ethan Kromhout" + } + ], + "emails": [ + { + "value": "ethan10@unc.edu", + "type": "primary" + } + ], + "phoneNumbers": [ + { + "value": "9194450056" + } + ] +} + +This limited version is being published as a part of +demonstrations for TechEx 2017, but should be expanded +further after that event. + +The connector currently supports DeleteOp, SearchOp, SchemaOp, TestOp +with DeleteOp not having any actions, import operations are supported +by the SearchOp. + +The configuration class supports items that are described in + +* src/main/resources/edu/unc/polygon/connector/amqp/Messages.properties + +A sample configuration XML is in the samples directory. diff --git a/connector-amqp-import/pom.xml b/connector-amqp-import/pom.xml new file mode 100644 index 0000000..353a071 --- /dev/null +++ b/connector-amqp-import/pom.xml @@ -0,0 +1,105 @@ + + + + 4.0.0 + + + connector-parent + com.evolveum.polygon + 1.4.2.14 + + + + edu.unc.polygon + connector-amqp-import + 0.1-SNAPSHOT + jar + + AMQP Connector + + + 1.8 + + edu.unc.polygon.connector.amqp + AmqpConnector + + 1.4 + + + + + evolveum-nexus-releases + Internal Releases + http://nexus.evolveum.com/nexus/content/repositories/releases/ + + + evolveum-nexus-snapshots + Internal Releases + http://nexus.evolveum.com/nexus/content/repositories/snapshots/ + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-resources-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + + org.apache.commons + commons-csv + ${commons.csv.version} + + + + com.rabbitmq + amqp-client + 4.0.2 + + + + + + com.googlecode.json-simple + json-simple + 1.1.1 + + + diff --git a/connector-amqp-import/samples/amqp-import.xml b/connector-amqp-import/samples/amqp-import.xml new file mode 100644 index 0000000..2aa285c --- /dev/null +++ b/connector-amqp-import/samples/amqp-import.xml @@ -0,0 +1,405 @@ + + AmqpImport + + 2017-09-21T14:11:57.837Z + + http://midpoint.evolveum.com/xml/ns/public/gui/channels-3#user + + + 2017-09-21T14:11:32.117Z + + + modify + c:ResourceType + + + com.evolveum.midpoint.model.impl.lens.ChangeExecutor.executeDelta + success + 1000000000000000107 + + AmqpImport + + success + + http://midpoint.evolveum.com/xml/ns/public/gui/channels-3#user + + + 2017-09-21T14:11:51.716Z + + + modify + c:ResourceType + + + com.evolveum.midpoint.model.impl.lens.ChangeExecutor.executeDelta + success + 1000000000000000156 + + AmqpImport + + success + + http://midpoint.evolveum.com/xml/ns/public/gui/channels-3#user + + + 2017-09-21T14:11:54.743Z + + + modify + c:ResourceType + + + com.evolveum.midpoint.model.impl.lens.ChangeExecutor.executeDelta + success + 1000000000000000185 + + AmqpImport + + success + + http://midpoint.evolveum.com/xml/ns/public/gui/channels-3#user + + + 2017-09-21T14:11:57.924Z + + + modify + c:ResourceType + + + com.evolveum.midpoint.model.impl.lens.ChangeExecutor.executeDelta + success + 1000000000000000214 + + AmqpImport + + success + + http://midpoint.evolveum.com/xml/ns/public/gui/channels-3#user + + + up + + + + + id + midpoint + midpoint_hr + payload + Guest + locahost + midpoint_hr + Guest + id + + + + + 2017-09-21T14:11:32.347Z + b770289cd65cdc8b-15db7329434d7839 + + + + + + + + + + + icfs:name + icfs:name + icfs:name + MESSAGE_OBJECT_CLASS___ACCOUNT__ + + + + + + + 120 + orgId + + + + + + + 130 + active + + + + + + + 140 + lastname + + + + + + + 150 + phone + + + + + + + 160 + firstname + + + + + + + id + 110 + __NAME__ + + + + + + + 180 + job + + + + + + + 190 + email + + + + + + + 200 + fullname + + + + + + + ConnId UID + 100 + read + + + + + + + + + + + account + default + true + ri:MESSAGE_OBJECT_CLASS___ACCOUNT__ + + icfs:name + Employee ID + + + $user/name + + + + + ri:fullname + + + $user/fullName + + + + + ri:firstname + + + $user/givenName + + + + + ri:lastname + + + $user/familyName + + + + + ri:orgId + + + $user/organizationalUnit + + + + + ri:job + + + $user/title + + + + + ri:phone + + + $user/telephoneNumber + + + + + ri:email + + + $user/emailAddress + + + + + + + weak + + + + + + + weak + + + + + + + + + + + 2017-09-21T14:11:32.345Z + a0989f9bf0bb5d59-12605cef28272abc + + + + + + + + + connector + + + + + + + true + + + true + + + true + + + true + + connector + + + + true + + + + + full + + + + true + + + c:name + + $account/attributes/id + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#deleteFocus + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + diff --git a/connector-amqp-import/src/main/assembly/connector.xml b/connector-amqp-import/src/main/assembly/connector.xml new file mode 100644 index 0000000..efca6d1 --- /dev/null +++ b/connector-amqp-import/src/main/assembly/connector.xml @@ -0,0 +1,47 @@ + + + + + connector + + + jar + + + false + + + + target/classes + + + + + + + lib + false + runtime + + net.tirasa.connid:connector-framework + + + + \ No newline at end of file diff --git a/connector-amqp-import/src/main/java/edu/unc/polygon/connector/amqp/AmqpConfiguration.java b/connector-amqp-import/src/main/java/edu/unc/polygon/connector/amqp/AmqpConfiguration.java new file mode 100644 index 0000000..f2333cf --- /dev/null +++ b/connector-amqp-import/src/main/java/edu/unc/polygon/connector/amqp/AmqpConfiguration.java @@ -0,0 +1,125 @@ +package edu.unc.polygon.connector.amqp; + +import org.identityconnectors.common.logging.Log; +import org.identityconnectors.framework.common.exceptions.ConfigurationException; +import org.identityconnectors.framework.common.objects.ObjectClass; +import org.identityconnectors.framework.spi.AbstractConfiguration; +import org.identityconnectors.framework.spi.ConfigurationProperty; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.*; +public class AmqpConfiguration extends AbstractConfiguration { + + private static final Log LOG = Log.getLog(AmqpConfiguration.class); + + //private ObjectClassHandlerConfiguration config = new ObjectClassHandlerConfiguration(); + + //private File objectClassDefinition = null; + private String AmqpUsername; + private String AmqpPassword; + private String AmqpHost; + private String AmqpExchangename; + private String AmqpQueuename; + private String AmqpRoutingkey; + private String AmqpUniqueAttribute; + private String AmqpNameAttribute; + private String AmqpPasswordAttribute; + private String AmqpScimPayloadField; + @ConfigurationProperty( + displayMessageKey = "UI_AMQP_USERNAME", + helpMessageKey = "UI_AMQP_USERNAME_HELP") + public String getAmqpUsername() { + return AmqpUsername; + } + @ConfigurationProperty( + displayMessageKey = "UI_AMQP_PASSWORD", + helpMessageKey = "UI_AMQP_PASSWORD_HELP") + public String getAmqpPassword() { + return AmqpPassword; + } + @ConfigurationProperty( + displayMessageKey = "UI_AMQP_HOST", + helpMessageKey = "UI_AMQP_HOST_HELP") + public String getAmqpHost() { + return AmqpHost; + } + @ConfigurationProperty( + displayMessageKey = "UI_AMQP_EXCHANGE_NAME", + helpMessageKey = "UI_AMQP_EXCHANGE_NAME_HELP") + public String getAmqpExchangename() { + return AmqpExchangename; + } + @ConfigurationProperty( + displayMessageKey = "UI_AMQP_QUEUE_NAME", + helpMessageKey = "UI_AMQP_QUEUE_NAME_HELP") + public String getAmqpQueuename() { + return AmqpQueuename; + } + @ConfigurationProperty( + displayMessageKey = "UI_AMQP_ROUTING_KEY", + helpMessageKey = "UI_AMQP_ROUTING_KEY_HELP") + public String getAmqpRoutingkey() { + return AmqpRoutingkey; + } + @ConfigurationProperty( + displayMessageKey = "UI_AMQP_UNIQUE_ATTRIBUTE", + helpMessageKey = "UI_AMQP_UNIQUE_ATTRIBUTE_HELP") + public String getAmqpUniqueAttribute() { + return AmqpUniqueAttribute; + } + @ConfigurationProperty( + displayMessageKey = "UI_AMQP_NAME_ATTRIBUTE", + helpMessageKey = "UI_AMQP_NAME_ATTRIBUTE_HELP") + public String getAmqpNameAttribute() { + return AmqpNameAttribute; + } + @ConfigurationProperty( + displayMessageKey = "UI_AMQP_PASSWORD_ATTRIBUTE", + helpMessageKey = "UI_AMQP_PASSWORD_ATTRIBUTE_HELP") + public String getAmqpPasswordAttribute() { + return AmqpPasswordAttribute; + } + @ConfigurationProperty( + displayMessageKey = "UI_AMQP_SCIM_PAYLOAD_FIELD", + helpMessageKey = "UI_AMQP_SCIM_PAYLOAD_FIELD_HELP") + public String getAmqpScimPayloadField() { + return AmqpScimPayloadField; + } + + public void setAmqpUsername(String AmqpUsername) { + this.AmqpUsername = AmqpUsername; + } + public void setAmqpPassword(String AmqpPassword) { + this.AmqpPassword = AmqpPassword; + } + public void setAmqpHost(String AmqpHost) { + this.AmqpHost = AmqpHost; + } + public void setAmqpExchangename(String AmqpExchangename) { + this.AmqpExchangename = AmqpExchangename; + } + public void setAmqpQueuename(String AmqpQueuename) { + this.AmqpQueuename = AmqpQueuename; + } + public void setAmqpRoutingkey(String AmqpRoutingkey) { + this.AmqpRoutingkey = AmqpRoutingkey; + } + public void setAmqpUniqueAttribute(String AmqpUniqueAttribute) { + this.AmqpUniqueAttribute = AmqpUniqueAttribute; + } + public void setAmqpNameAttribute(String AmqpNameAttribute) { + this.AmqpNameAttribute = AmqpNameAttribute; + } + public void setAmqpPasswordAttribute(String AmqpPasswordAttribute) { + this.AmqpPasswordAttribute = AmqpPasswordAttribute; + } + public void setAmqpScimPayloadField(String AmqpScimPayloadField) { + this.AmqpScimPayloadField = AmqpScimPayloadField; + } + @Override + public void validate() { + // TODO + } + +} diff --git a/connector-amqp-import/src/main/java/edu/unc/polygon/connector/amqp/AmqpConnector.java b/connector-amqp-import/src/main/java/edu/unc/polygon/connector/amqp/AmqpConnector.java new file mode 100644 index 0000000..359d974 --- /dev/null +++ b/connector-amqp-import/src/main/java/edu/unc/polygon/connector/amqp/AmqpConnector.java @@ -0,0 +1,361 @@ +package edu.unc.polygon.connector.amqp; + +import org.identityconnectors.common.logging.Log; +import org.identityconnectors.common.security.GuardedString; +import org.identityconnectors.framework.common.exceptions.ConfigurationException; +import org.identityconnectors.framework.common.exceptions.ConnectorException; +import org.identityconnectors.framework.common.objects.*; +import org.identityconnectors.framework.common.objects.filter.FilterTranslator; +import org.identityconnectors.framework.spi.Configuration; +import org.identityconnectors.framework.spi.Connector; +import org.identityconnectors.framework.spi.ConnectorClass; +import org.identityconnectors.framework.spi.operations.*; +import org.identityconnectors.common.Base64; +import org.identityconnectors.common.StringUtil; +import org.identityconnectors.common.security.GuardedByteArray; +import org.identityconnectors.common.security.GuardedString; + +import com.rabbitmq.client.*; + +import java.util.Iterator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.io.*; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVPrinter; +import org.apache.commons.csv.CSVRecord; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + + +@ConnectorClass(displayNameKey = "UI_AMQP_CONNECTOR_NAME", configurationClass = AmqpConfiguration.class) +public class AmqpConnector implements Connector, DeleteOp, SearchOp, SchemaOp, TestOp { + +private static final Log LOG = Log.getLog(AmqpConnector.class); + + private AmqpConfiguration configuration; + + @Override + public Configuration getConfiguration() { + return configuration; + } + + + @Override + public void init(Configuration configuration) { + LOG.info(">>> Initializing connector"); + + if (!(configuration instanceof AmqpConfiguration)) { + throw new ConfigurationException("Configuration is not instance of " + AmqpConfiguration.class.getName()); + } + + AmqpConfiguration amqpConfig = (AmqpConfiguration) configuration; + amqpConfig.validate(); + this.configuration = amqpConfig; + LOG.info(">>> Connector initialization finished"); + } + @Override + public void dispose() { + configuration = null; + //handler = null; + } + @Override + public FilterTranslator createFilterTranslator(ObjectClass oc, OperationOptions oo) { + LOG.info("inside createFilterTranslator"); + return new AmqpFilterTranslator(); + } + private boolean isUniqueAndNameAttributeEqual() { + LOG.info("inside isUniqueAndNameAttributeEqual"); + String uniqueAttribute = configuration.getAmqpUniqueAttribute(); + String nameAttribute = configuration.getAmqpNameAttribute(); + + return uniqueAttribute == null ? nameAttribute == null : uniqueAttribute.equals(nameAttribute); + } + @Override + public void test() { + try { + ConnectionFactory factory = new ConnectionFactory(); + factory.setHost(configuration.getAmqpHost()); + factory.setUsername(configuration.getAmqpUsername()); + factory.setPassword(configuration.getAmqpPassword()); + Connection connection = factory.newConnection(); + Channel channel = connection.createChannel(); + boolean connected = channel.isOpen(); + if (connected) { + LOG.info("Testing connection succeeded"); + } + else { + LOG.info("Testing connection failed"); + } + connection.close(); + } catch (Exception teste) { + LOG.info("in exception teste" + teste.getStackTrace()); + //connection.close(); + } + + } + @Override + public Schema schema() { + LOG.info(">>> schema started"); + + SchemaBuilder builder = new SchemaBuilder(AmqpConnector.class); + Set attributes= new HashSet(); + AttributeInfoBuilder id = new AttributeInfoBuilder(); + id.setName("id"); + id.setCreateable(true); + id.setUpdateable(true); + id.setReadable(true); + id.setRequired(false); + id.setMultiValued(false); + attributes.add(id.build()); + AttributeInfoBuilder fullname = new AttributeInfoBuilder(); + fullname.setName("fullname"); + fullname.setCreateable(true); + fullname.setUpdateable(true); + fullname.setReadable(true); + fullname.setRequired(false); + fullname.setMultiValued(false); + attributes.add(fullname.build()); + AttributeInfoBuilder firstname = new AttributeInfoBuilder(); + firstname.setName("firstname"); + firstname.setCreateable(true); + firstname.setUpdateable(true); + firstname.setReadable(true); + firstname.setRequired(false); + firstname.setMultiValued(false); + attributes.add(firstname.build()); + AttributeInfoBuilder lastname = new AttributeInfoBuilder(); + lastname.setName("lastname"); + lastname.setCreateable(true); + lastname.setUpdateable(true); + lastname.setReadable(true); + lastname.setRequired(false); + lastname.setMultiValued(false); + attributes.add(lastname.build()); + AttributeInfoBuilder orgId = new AttributeInfoBuilder(); + orgId.setName("orgId"); + orgId.setCreateable(true); + orgId.setUpdateable(true); + orgId.setReadable(true); + orgId.setRequired(false); + orgId.setMultiValued(false); + attributes.add(orgId.build()); + AttributeInfoBuilder job = new AttributeInfoBuilder(); + job.setName("job"); + job.setCreateable(true); + job.setUpdateable(true); + job.setReadable(true); + job.setRequired(false); + job.setMultiValued(false); + attributes.add(job.build()); + AttributeInfoBuilder email = new AttributeInfoBuilder(); + email.setName("email"); + email.setCreateable(true); + email.setUpdateable(true); + email.setReadable(true); + email.setRequired(false); + email.setMultiValued(false); + attributes.add(email.build()); + AttributeInfoBuilder phone = new AttributeInfoBuilder(); + phone.setName("phone"); + phone.setCreateable(true); + phone.setUpdateable(true); + phone.setReadable(true); + phone.setRequired(false); + phone.setMultiValued(false); + attributes.add(phone.build()); + AttributeInfoBuilder active = new AttributeInfoBuilder(); + active.setName("active"); + active.setCreateable(true); + active.setUpdateable(true); + active.setReadable(true); + active.setRequired(false); + active.setMultiValued(false); + attributes.add(active.build()); + builder.defineObjectClass(ObjectClass.ACCOUNT.getDisplayNameKey(),attributes); + LOG.info(">>> schema finished"); + return builder.build(); + } + + @Override + public void executeQuery(ObjectClass oc, String uid, ResultsHandler handler, OperationOptions oo) { + LOG.info(">>> executeQuery "); + try { + LOG.info("about to create factory"); + ConnectionFactory factory = new ConnectionFactory(); + factory.setHost(configuration.getAmqpHost()); + factory.setUsername(configuration.getAmqpUsername()); + factory.setPassword(configuration.getAmqpPassword()); + Connection connection = factory.newConnection(); + Channel channel = connection.createChannel(); + boolean durable = true; + channel.exchangeDeclare(configuration.getAmqpExchangename(), BuiltinExchangeType.TOPIC, durable); + String queueName = channel.queueDeclare().getQueue(); + queueName = configuration.getAmqpQueuename(); + LOG.info("about to bind queue" + queueName + configuration.getAmqpExchangename() + configuration.getAmqpRoutingkey()); + channel.queueBind(queueName,configuration.getAmqpExchangename(),configuration.getAmqpRoutingkey()); + boolean connected = channel.isOpen(); + if (connected) { + LOG.info("Testing connection succeeded"); + } + else { + LOG.info("Testing connection failed"); + } + boolean autoAck = false; + while (true) { + LOG.info("about to get response"); + GetResponse response = channel.basicGet(queueName, autoAck); + /* A null would mean no messages are available to process */ + if(response != null) { + String message = ""; + message = new String(response.getBody(), "UTF-8"); + LOG.info("just got the message body"); + long deliveryTag = response.getEnvelope().getDeliveryTag(); + channel.basicAck(deliveryTag, false); + Reader in = new StringReader(message); + String id = ""; + String fullname = ""; + String firstname = ""; + String lastname = ""; + String orgId = "TIER"; + String job = "Developer"; + String email = ""; + String phone = ""; + String active = "true"; + try { + JSONParser jsonParser = new JSONParser(); + JSONObject jsonObject = (JSONObject) jsonParser.parse(message); + LOG.info("just did initial object parse of message"); + JSONObject scimMessage = (JSONObject) jsonObject.get(configuration.getAmqpScimPayloadField()); + LOG.info("just got the scim message"); + LOG.info("payload field " + configuration.getAmqpScimPayloadField()); + id = (String) scimMessage.get(configuration.getAmqpNameAttribute()); + LOG.info("id " + id); + LOG.info("about to get names"); + JSONArray names = (JSONArray) scimMessage.get("names"); + LOG.info("got names"); + Iterator i = names.iterator(); + while (i.hasNext()) { + LOG.info("inside name iterator"); + JSONObject name = (JSONObject) i.next(); + fullname = (String) name.get("formatted"); + LOG.info(fullname); + firstname = (String) name.get("givenName"); + LOG.info(firstname); + lastname = (String) name.get("familyName"); + LOG.info(lastname); + break; + } + LOG.info("finished names"); + JSONArray emails = (JSONArray) scimMessage.get("emails"); + LOG.info("got emails"); + i = emails.iterator(); + while (i.hasNext()) { + JSONObject emailEntry = (JSONObject) i.next(); + email = (String) emailEntry.get("value"); + String type = (String) emailEntry.get("type"); + if (type.equals("primary")) { + break; + } + } + JSONArray phoneNumbers = (JSONArray) scimMessage.get("phoneNumbers"); + i = phoneNumbers.iterator(); + while (i.hasNext()) { + JSONObject phoneNumber = (JSONObject) i.next(); + phone = (String) phoneNumber.get("value"); + break; + } + LOG.info("done parsing json"); + } catch (Exception e) { + LOG.info("Exception parsing json" + e.getMessage()); + LOG.info("Exception parsing json" + e.getCause()); + LOG.info("Exception parsing json" + e.getStackTrace()); + } + + HashMap record = new HashMap(); + record.put("id",id); + record.put("fullname",fullname); + record.put("lastname",lastname); + record.put("firstname",firstname); + record.put("orgId",orgId); + record.put("job",job); + record.put("email",email); + record.put("phone",phone); + record.put("active",active); + + LOG.info("about to call createConnectorObject"); + ConnectorObject obj = createConnectorObject(record); + LOG.info("about to call handler"); + //ResultsHandler handler = new ResultsHandler(); + handler.handle(obj); + LOG.info("finished call handler"); + + } else { + LOG.info("message response was null"); + break; + } + } + connection.close(); + } catch (Exception queryEx) { + LOG.info("in exception queryEx" + queryEx.getMessage()); + LOG.info("in exception queryEx" + queryEx.getCause()); + LOG.info("in exception queryEx" + queryEx.getStackTrace()); + //connection.close(); + } + LOG.info(">>> executeQuery finished"); + } + private ConnectorObject createConnectorObject(HashMap record) { + ConnectorObjectBuilder builder = new ConnectorObjectBuilder(); + LOG.info("inside createConnectorObject "); + + for ( Map.Entry entry : record.entrySet()) { + String name = entry.getKey(); + String value = record.get(name); + LOG.info("inside record breakdown in createConnectorObject name == " + name + "value == " + value); + if (StringUtil.isEmpty(value)) { + continue; + } + + if (name.equals(configuration.getAmqpUniqueAttribute())) { + builder.setUid(value); + + if (!isUniqueAndNameAttributeEqual()) { + continue; + } + } + + if (name.equals(configuration.getAmqpNameAttribute())) { + builder.setName(new Name(value)); + continue; + } + + if (name.equals(configuration.getAmqpPasswordAttribute())) { + builder.addAttribute(OperationalAttributes.PASSWORD_NAME, new GuardedString(value.toCharArray())); + continue; + } + + builder.addAttribute(name, value); + } + + LOG.info("build completed"); + return builder.build(); + } + + @Override + public void delete(ObjectClass oc, Uid uid, OperationOptions oo) { + LOG.info(">>> delete {0} {1} {2}", oc, uid, oo); + + //getHandler(oc).delete(oc, uid, oo); + + LOG.info(">>> delete finished"); + } + +} diff --git a/connector-amqp-import/src/main/java/edu/unc/polygon/connector/amqp/AmqpFilterTranslator.java b/connector-amqp-import/src/main/java/edu/unc/polygon/connector/amqp/AmqpFilterTranslator.java new file mode 100644 index 0000000..d5024a9 --- /dev/null +++ b/connector-amqp-import/src/main/java/edu/unc/polygon/connector/amqp/AmqpFilterTranslator.java @@ -0,0 +1,33 @@ +package edu.unc.polygon.connector.amqp; + +import org.identityconnectors.framework.common.objects.Attribute; +import org.identityconnectors.framework.common.objects.Uid; +import org.identityconnectors.framework.common.objects.filter.AbstractFilterTranslator; +import org.identityconnectors.framework.common.objects.filter.EqualsFilter; + +import java.util.List; + +public class AmqpFilterTranslator extends AbstractFilterTranslator { + + @Override + protected String createEqualsExpression(EqualsFilter filter, boolean not) { + if (not) { + return null; + } + + Attribute attr = filter.getAttribute(); + if (!attr.is(Uid.NAME)) { + return null; + } + + List values = attr.getValue(); + if (values.isEmpty()) { + return null; + } + + Object value = values.get(0); + + return value != null ? value.toString() : null; + } +} + diff --git a/connector-amqp-import/src/main/resources/edu/unc/polygon/connector/amqp/Messages.properties b/connector-amqp-import/src/main/resources/edu/unc/polygon/connector/amqp/Messages.properties new file mode 100644 index 0000000..6c40243 --- /dev/null +++ b/connector-amqp-import/src/main/resources/edu/unc/polygon/connector/amqp/Messages.properties @@ -0,0 +1,21 @@ +UI_AMQP_CONNECTOR_NAME=AMQP Connector +UI_AMQP_USERNAME=AMQP Username +UI_AMQP_USERNAME_HELP=The Username to authenticate to the rabbitMQ virtualhost. +UI_AMQP_PASSWORD=AMQP Password +UI_AMQP_PASSWORD_HELP=Password for the rabbitMQ virtualhost connection. +UI_AMQP_HOST=AMQP Host +UI_AMQP_HOST_HELP=Hostname or IP of the server running rabbitMQ. +UI_AMQP_EXCHANGE_NAME=AMQP Exchange Name +UI_AMQP_EXCHANGE_NAME_HELP=The exchange or topic on the rabbitMQ virtualhost. +UI_AMQP_QUEUE_NAME=AMQP Queue Name +UI_AMQP_QUEUE_NAME_HELP=The queue on the rabbitMQ exchange. +UI_AMQP_ROUTING_KEY=AMQP Routing Key +UI_AMQP_ROUTING_KEY_HELP=The routing key for messages on the queue to process to import accounts. +UI_AMQP_UNIQUE_ATTRIBUTE=AMQP Unique Attribute +UI_AMQP_UNIQUE_ATTRIBUTE_HELP=The unique attribute for accounts on the source system or messages (id, externalId,userName etc.), may be the same as the name attribute. +UI_AMQP_NAME_ATTRIBUTE=AMQP Name Attribute +UI_AMQP_NAME_ATTRIBUTE_HELP=The name attribure for accounts in the source system or messages. +UI_AMQP_PASSWORD_ATTRIBUTE=AMQP Password Attribute +UI_AMQP_PASSWORD_ATTRIBUTE_HELP=The password attribute for the account from the source system or messages. +UI_AMQP_SCIM_PAYLOAD_FIELD=Scim Payload Field +UI_AMQP_SCIM_PAYLOAD_FIELD_HELP=The field inside the AMQP message that holds the SCIM payload.