diff --git a/connector-amqp-import/README b/connector-amqp-import/README index 354c70d..944a296 100644 --- a/connector-amqp-import/README +++ b/connector-amqp-import/README @@ -5,41 +5,59 @@ 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: +https://github.internet2.edu/TIER/schema/blob/master/schema/core-person.json { - "id": "EMPP00010", - "names": [ + "name": { + "familyName": "Jansen", + "givenName": "Jo", + "middleName": "ethan", + "nameType": "Legal" + }, + "birthDate": "1955-12-10", + "logon-id": "jjansen", + "subject-id": "34-546877", + "priorSubject-id": [ { - "givenName": "Ethan", - "familyName": "Kromhout", - "formatted": "Ethan Kromhout" + "id": "34-546876" } ], - "emails": [ + "sourceId": [ + { + "id": "357A225", + "source": "SIS" + }, { - "value": "ethan10@unc.edu", - "type": "primary" + "id": "jansen121", + "source": "HR" } ], - "phoneNumbers": [ + "email": [ { - "value": "9194450056" + "emailAddress": "jjansen@goo.edu", + "emailType": "primary" } - ] + ], + "phone": [ + { + "phoneNumber": "9194450056", + "phoneType": "Work" + }, + { + "phoneNumber": "9194481296", + "phoneType": "Mobile" + } + ], + "personalPronoun": "Mr" } -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. +__NAME__ currently set to required email attribute. +__UID__ set to sourceId attribute, a concatenation of source + '-' + id. + The configuration class supports items that are described in * src/main/resources/edu/unc/polygon/connector/amqp/Messages.properties diff --git a/connector-amqp-import/pom.xml b/connector-amqp-import/pom.xml index 353a071..9f81779 100644 --- a/connector-amqp-import/pom.xml +++ b/connector-amqp-import/pom.xml @@ -28,7 +28,7 @@ edu.unc.polygon connector-amqp-import - 0.1-SNAPSHOT + 0.3-SNAPSHOT jar AMQP Connector @@ -89,12 +89,12 @@ 4.0.2 - + com.googlecode.json-simple 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 index 49a77f8..6a8931c 100644 --- 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 @@ -2,8 +2,9 @@ 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.exceptions.ConfigurationException; +//import org.identityconnectors.framework.common.exceptions.ConnectorException; +import org.identityconnectors.framework.common.exceptions.*; import org.identityconnectors.framework.common.objects.*; import org.identityconnectors.framework.common.objects.filter.FilterTranslator; import org.identityconnectors.framework.spi.Configuration; @@ -109,14 +110,89 @@ public Schema schema() { 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 sourceId = new AttributeInfoBuilder("sourceId", String.class); + //sourceId.setName("sourceId"); + sourceId.setCreateable(true); + sourceId.setUpdateable(true); + sourceId.setReadable(true); + sourceId.setRequired(false); + sourceId.setMultiValued(true); + attributes.add(sourceId.build()); + AttributeInfoBuilder priorSubjectId = new AttributeInfoBuilder("priorSubjectId", String.class); + //priorSubjectId.setName("priorSubjectId"); + priorSubjectId.setCreateable(true); + priorSubjectId.setNativeName("priorSubject-id"); + priorSubjectId.setUpdateable(true); + priorSubjectId.setReadable(true); + priorSubjectId.setRequired(false); + priorSubjectId.setMultiValued(true); + attributes.add(priorSubjectId.build()); + AttributeInfoBuilder personalPronoun = new AttributeInfoBuilder(); + personalPronoun.setName("personalPronoun"); + personalPronoun.setCreateable(true); + personalPronoun.setUpdateable(true); + personalPronoun.setReadable(true); + personalPronoun.setRequired(false); + personalPronoun.setMultiValued(false); + attributes.add(personalPronoun.build()); + AttributeInfoBuilder subjectId = new AttributeInfoBuilder(); + subjectId.setName("subjectId"); + subjectId.setNativeName("subject-id"); + subjectId.setCreateable(true); + subjectId.setUpdateable(true); + subjectId.setReadable(true); + subjectId.setRequired(false); + subjectId.setMultiValued(false); + attributes.add(subjectId.build()); + AttributeInfoBuilder loginId = new AttributeInfoBuilder(); + loginId.setName("loginId"); + loginId.setNativeName("login-id"); + loginId.setCreateable(true); + loginId.setUpdateable(true); + loginId.setReadable(true); + loginId.setRequired(false); + loginId.setMultiValued(false); + attributes.add(loginId.build()); + AttributeInfoBuilder birthDate = new AttributeInfoBuilder(); + birthDate.setName("birthDate"); + birthDate.setCreateable(true); + birthDate.setUpdateable(true); + birthDate.setReadable(true); + birthDate.setRequired(false); + birthDate.setMultiValued(false); + attributes.add(birthDate.build()); + AttributeInfoBuilder nameType = new AttributeInfoBuilder(); + nameType.setName("nameType"); + nameType.setCreateable(true); + nameType.setUpdateable(true); + nameType.setReadable(true); + nameType.setRequired(false); + nameType.setMultiValued(false); + attributes.add(nameType.build()); + AttributeInfoBuilder middleName = new AttributeInfoBuilder(); + middleName.setName("middleName"); + middleName.setCreateable(true); + middleName.setUpdateable(true); + middleName.setReadable(true); + middleName.setRequired(false); + middleName.setMultiValued(false); + attributes.add(middleName.build()); + AttributeInfoBuilder givenName = new AttributeInfoBuilder(); + givenName.setName("givenName"); + givenName.setCreateable(true); + givenName.setUpdateable(true); + givenName.setReadable(true); + givenName.setRequired(false); + givenName.setMultiValued(false); + attributes.add(givenName.build()); + AttributeInfoBuilder familyName = new AttributeInfoBuilder(); + familyName.setName("familyName"); + familyName.setCreateable(true); + familyName.setUpdateable(true); + familyName.setReadable(true); + familyName.setRequired(false); + familyName.setMultiValued(false); + attributes.add(familyName.build()); AttributeInfoBuilder fullname = new AttributeInfoBuilder(); fullname.setName("fullname"); fullname.setCreateable(true); @@ -157,21 +233,21 @@ public Schema schema() { job.setRequired(false); job.setMultiValued(false); attributes.add(job.build()); - AttributeInfoBuilder email = new AttributeInfoBuilder(); - email.setName("email"); + AttributeInfoBuilder email = new AttributeInfoBuilder("email", String.class); + //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"); + AttributeInfoBuilder phone = new AttributeInfoBuilder("phone", String.class); + //phone.setName("phone"); phone.setCreateable(true); phone.setUpdateable(true); phone.setReadable(true); phone.setRequired(false); - phone.setMultiValued(false); + phone.setMultiValued(true); attributes.add(phone.build()); AttributeInfoBuilder active = new AttributeInfoBuilder(); active.setName("active"); @@ -222,14 +298,10 @@ public void executeQuery(ObjectClass oc, AmqpFilter filter, ResultsHandler handl 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 = ""; + ConnectorObjectBuilder builder = new ConnectorObjectBuilder(); + LOG.info("ConnectorObjectBuilder instantiated "); + String orgId = ""; + String job = ""; String active = "true"; try { JSONParser jsonParser = new JSONParser(); @@ -238,41 +310,136 @@ public void executeQuery(ObjectClass oc, AmqpFilter filter, ResultsHandler handl 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); + /*if ( scimMessage.containsKey(configuration.getAmqpUniqueAttribute()) && scimMessage.get(configuration.getAmqpUniqueAttribute()) != null && !scimMessage.get(configuration.getAmqpUniqueAttribute()).equals("") ) { + id = (String) scimMessage.get(configuration.getAmqpUniqueAttribute()); + LOG.info("id " + id); + } + else { + throw new InvalidAttributeValueException("Missing mandatory attribute " + configuration.getAmqpNameAttribute()); + }*/ + if ( scimMessage.containsKey("birthDate") && scimMessage.get("birthDate") != null && !scimMessage.get("birthDate").equals("") ) { + String birthDate = (String) scimMessage.get("birthDate"); + LOG.info(birthDate); + builder.addAttribute("birthDate", birthDate); + } + if ( scimMessage.containsKey("logon-id") && scimMessage.get("logon-id") != null && !scimMessage.get("logon-id").equals("") ) { + String loginId = (String) scimMessage.get("logon-id"); + LOG.info(loginId); + builder.addAttribute("loginId", loginId); + } + if ( scimMessage.containsKey("subject-id") && scimMessage.get("subject-id") != null && !scimMessage.get("subject-id").equals("") ) { + String subjectId = (String) scimMessage.get("subject-id"); + LOG.info(subjectId); + builder.addAttribute("subjectId", subjectId); + } + if ( scimMessage.containsKey("personalPronoun") && scimMessage.get("personalPronoun") != null && !scimMessage.get("personalPronoun").equals("") ) { + String personalPronoun = (String) scimMessage.get("personalPronoun"); + LOG.info(personalPronoun); + builder.addAttribute("personalPronoun", personalPronoun); + } 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; + if ( scimMessage.containsKey("name") && scimMessage.get("name") != null && !scimMessage.get("name").equals("") ) { + JSONArray names = (JSONArray) scimMessage.get("name"); + LOG.info("got names"); + Iterator i = names.iterator(); + while (i.hasNext()) { + LOG.info("inside name iterator"); + JSONObject name = (JSONObject) i.next(); + if ( name.containsKey("middleName") ) { + String middleName = (String) name.get("middleName"); + LOG.info(middleName); + builder.addAttribute("middleName", middleName); + } + if ( name.containsKey("givenName") ) { + String givenName = (String) name.get("givenName"); + LOG.info(givenName); + builder.addAttribute("givenName", givenName); + } + if ( name.containsKey("familyName") ) { + String familyName = (String) name.get("familyName"); + LOG.info(familyName); + builder.addAttribute("familyName", familyName); + } + if ( name.containsKey("nameType") ) { + String nameType = (String) name.get("nameType"); + LOG.info(nameType); + builder.addAttribute("nameType", nameType); + } + break; + } + LOG.info("finished names"); + } + else { + throw new InvalidAttributeValueException("Missing mandatory attribute name"); } - 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; - } + if ( scimMessage.containsKey("email") && scimMessage.get("email") != null && !scimMessage.get("email").equals("") ) { + JSONArray emails = (JSONArray) scimMessage.get("email"); + LOG.info("got emails"); + boolean hasPrimary = false; + Iterator i = emails.iterator(); + while (i.hasNext()) { + JSONObject emailEntry = (JSONObject) i.next(); + String emailAddress = (String) emailEntry.get("emailAddress"); + String emailType = (String) emailEntry.get("emailType"); + String email = emailType + "." + emailAddress; + if ( emailAddress != null && !emailAddress.equals("") ) { + LOG.info ("adding email " + email); + builder.addAttribute("email",email); + if (emailType.equals("primary")) { + builder.setName(new Name(emailAddress)); + //builder.setUid(new Uid(emailAddress)); + hasPrimary = true; + } + } + } + if ( !hasPrimary ) { + JSONObject emailEntry = (JSONObject) emails.get(0); + String emailAddress = (String) emailEntry.get("emailAddress"); + builder.setName(new Name(emailAddress)); + } } - JSONArray phoneNumbers = (JSONArray) scimMessage.get("phoneNumbers"); - i = phoneNumbers.iterator(); - while (i.hasNext()) { - JSONObject phoneNumber = (JSONObject) i.next(); - phone = (String) phoneNumber.get("value"); - break; + else { + throw new InvalidAttributeValueException("Missing mandatory attribute email1"); + } + if ( scimMessage.containsKey("phone") && scimMessage.get("phone") != null && !scimMessage.get("phone").equals("") ) { + JSONArray phoneNumbers = (JSONArray) scimMessage.get("phone"); + LOG.info("got array of phones size " + String.valueOf(phoneNumbers.size())); + Iterator j = phoneNumbers.iterator(); + while (j.hasNext()) { + JSONObject phoneEntry = (JSONObject) j.next(); + String phoneNumber = (String) phoneEntry.get("phoneNumber"); + String phoneType = (String) phoneEntry.get("phoneType"); + String phone = phoneType + "." + phoneNumber; + LOG.info("processing phoneNumber " + phoneNumber + "-" + phoneType + "-" + phone + "-"); + if ( phoneNumber != null && !phoneNumber.equals("") ) { + LOG.info("adding phone " + phone); + builder.addAttribute("phone",phone); + } + } + } + if ( scimMessage.containsKey("sourceId") && scimMessage.get("sourceId") != null && !scimMessage.get("sourceId").equals("") ) { + JSONArray sourceIds = (JSONArray) scimMessage.get("sourceId"); + Iterator i = sourceIds.iterator(); + while (i.hasNext()) { + JSONObject sourceIdEntry = (JSONObject) i.next(); + String id = (String) sourceIdEntry.get("id"); + String source = (String) sourceIdEntry.get("source"); + String sourceId = source + "-" + id; + builder.addAttribute("sourceId",sourceId); + builder.setUid(source + "-" + id); + } + } + else { + throw new InvalidAttributeValueException("Missing mandatory attribute sourceId"); + } + if ( scimMessage.containsKey("priorSubject-id") && scimMessage.get("priorSubject-id") != null && !scimMessage.get("priorSubject-id").equals("") ) { + JSONArray priorSubjectIds = (JSONArray) scimMessage.get("priorSubject-id"); + Iterator i = priorSubjectIds.iterator(); + while (i.hasNext()) { + JSONObject priorSubectIdEntry = (JSONObject) i.next(); + String id = (String) priorSubectIdEntry.get("id"); + builder.addAttribute("priorSubjectId",id); + } } LOG.info("done parsing json"); } catch (Exception e) { @@ -281,19 +448,20 @@ public void executeQuery(ObjectClass oc, AmqpFilter filter, ResultsHandler handl LOG.info("Exception parsing json" + e.getStackTrace()); } - HashMap record = new HashMap(); + /*HashMap record = new HashMap(); record.put("id",id); - record.put("fullname",fullname); - record.put("lastname",lastname); - record.put("firstname",firstname); + record.put("middleName",middleName); + record.put("familyName",familyName); + record.put("givenName",givenName); + record.put("nameType",nameType); record.put("orgId",orgId); record.put("job",job); record.put("email",email); record.put("phone",phone); - record.put("active",active); + record.put("active",active);*/ LOG.info("about to call createConnectorObject"); - ConnectorObject obj = createConnectorObject(record); + ConnectorObject obj = builder.build(); LOG.info("about to call handler"); //ResultsHandler handler = new ResultsHandler(); handler.handle(obj); @@ -313,7 +481,7 @@ public void executeQuery(ObjectClass oc, AmqpFilter filter, ResultsHandler handl } LOG.info(">>> executeQuery finished"); } - private ConnectorObject createConnectorObject(HashMap record) { +/* private ConnectorObject createConnectorObject(HashMap record) { ConnectorObjectBuilder builder = new ConnectorObjectBuilder(); LOG.info("inside createConnectorObject "); @@ -348,7 +516,7 @@ private ConnectorObject createConnectorObject(HashMap record) { LOG.info("build completed"); return builder.build(); - } + } */ @Override public void delete(ObjectClass oc, Uid uid, OperationOptions oo) {