Commit 79586a83 authored by Radovan Semancik's avatar Radovan Semancik
Browse files

Cleaup of old polysting values (MID-5210)

parent d7531393
......@@ -21,6 +21,7 @@ import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -927,6 +928,9 @@ public abstract class AbstractLdapConnector<C extends AbstractLdapConfiguration>
Entry entryRead = searchSingleEntry(connectionManager, entry.getDn(), LdapUtil.createAllSearchFilter(), SearchScope.OBJECT,
new String[]{ uidAttributeName }, "re-reading entry to get UID", options);
if (entryRead == null) {
throw new UnknownUidException("Cannot re-reading entry to get UID, entry was not found: "+entry.getDn());
}
org.apache.directory.api.ldap.model.entry.Attribute uidLdapAttribute = entryRead.get(uidAttributeName);
if (uidLdapAttribute == null) {
throw new InvalidAttributeValueException("No value for UID attribute "+uidAttributeName+" in object "+dnStringFromName);
......@@ -1103,52 +1107,6 @@ public abstract class AbstractLdapConnector<C extends AbstractLdapConfiguration>
return AttributeDeltaBuilder.build(Uid.NAME, string);
}
private void addLdapModificationString(List<Modification> ldapModifications,
ModificationOperation modOp, String ldapAttributeName, List<Object> values) {
if (values == null) {
return;
}
String[] stringValues = new String[values.size()];
int i = 0;
for(Object val: values) {
stringValues[i] = (String)val;
i++;
}
ldapModifications.add(new DefaultModification(modOp, ldapAttributeName, stringValues));
}
private void addLdapModification(List<Modification> ldapModifications,
ModificationOperation modOp, AttributeType ldapAttributeType, List<Object> connIdValues) {
if (connIdValues == null) {
return;
}
if (schemaTranslator.isPolyAttribute(ldapAttributeType, connIdValues)) {
Map<String,List<Value>> valueMap = schemaTranslator.toLdapPolyValues(ldapAttributeType, connIdValues);
for (Map.Entry<String, List<Value>> valueMapEntry : valueMap.entrySet()) {
// Do NOT set AttributeType here
// The attributeType might not match the Value class
// e.g. human-readable jpegPhoto attribute will expect StringValue
DefaultAttribute ldapAttribute = new DefaultAttribute(valueMapEntry.getKey(), valueMapEntry.getValue().toArray(new Value[valueMapEntry.getValue().size()]));
ldapModifications.add(new DefaultModification(modOp, ldapAttribute));
}
} else {
List<Value> ldapValues = schemaTranslator.toLdapValues(ldapAttributeType, connIdValues);
if (ldapValues == null || ldapValues.isEmpty()) {
// Do NOT set AttributeType here
// The attributeType might not match the Value class
// e.g. human-readable jpegPhoto attribute will expect StringValue
ldapModifications.add(new DefaultModification(modOp, ldapAttributeType.getName()));
} else {
// Do NOT set AttributeType here
// The attributeType might not match the Value class
// e.g. human-readable jpegPhoto attribute will expect StringValue
DefaultAttribute ldapAttribute = new DefaultAttribute(ldapAttributeType.getName(), ldapValues.toArray(new Value[ldapValues.size()]));
ldapModifications.add(new DefaultModification(modOp, ldapAttribute));
}
}
}
protected void modify(Dn dn, List<Modification> modifications, OperationOptions options) {
LdapNetworkConnection connection = connectionManager.getConnection(dn, options);
try {
......@@ -1203,11 +1161,107 @@ public abstract class AbstractLdapConnector<C extends AbstractLdapConfiguration>
&& !ArrayUtils.contains(configuration.getOperationalAttributes(), delta.getName())) {
throw new InvalidAttributeValueException("Unknown attribute "+delta.getName()+" in object class "+connIdObjectClass);
}
addLdapModification(modifications, ModificationOperation.REPLACE_ATTRIBUTE, ldapAttributeType, delta.getValuesToReplace());
addLdapModification(modifications, ModificationOperation.ADD_ATTRIBUTE, ldapAttributeType, delta.getValuesToAdd());
addLdapModification(modifications, ModificationOperation.REMOVE_ATTRIBUTE, ldapAttributeType, delta.getValuesToRemove());
addLdapModification(dn, modifications, ModificationOperation.REPLACE_ATTRIBUTE, ldapAttributeType, delta.getValuesToReplace());
addLdapModification(dn, modifications, ModificationOperation.ADD_ATTRIBUTE, ldapAttributeType, delta.getValuesToAdd());
addLdapModification(dn, modifications, ModificationOperation.REMOVE_ATTRIBUTE, ldapAttributeType, delta.getValuesToRemove());
}
private void addLdapModificationString(List<Modification> ldapModifications,
ModificationOperation modOp, String ldapAttributeName, List<Object> values) {
if (values == null) {
return;
}
String[] stringValues = new String[values.size()];
int i = 0;
for(Object val: values) {
stringValues[i] = (String)val;
i++;
}
ldapModifications.add(new DefaultModification(modOp, ldapAttributeName, stringValues));
}
private void addLdapModification(Dn dn, List<Modification> ldapModifications,
ModificationOperation modOp, AttributeType ldapAttributeType, List<Object> connIdValues) {
if (connIdValues == null) {
return;
}
if (schemaTranslator.isPolyAttribute(ldapAttributeType, connIdValues)) {
addLdapModificationPoly(dn, ldapModifications, modOp, ldapAttributeType, connIdValues);
} else {
addLdapModificationSimple(dn, ldapModifications, modOp, ldapAttributeType, connIdValues);
}
}
/**
* For simple (non-poly) attributes. The usual stuff. Used for most cases.
*/
private void addLdapModificationSimple(Dn dn, List<Modification> ldapModifications,
ModificationOperation modOp, AttributeType ldapAttributeType, List<Object> connIdValues) {
List<Value> ldapValues = schemaTranslator.toLdapValues(ldapAttributeType, connIdValues);
if (ldapValues == null || ldapValues.isEmpty()) {
// Do NOT set AttributeType here
// The attributeType might not match the Value class
// e.g. human-readable jpegPhoto attribute will expect StringValue
ldapModifications.add(new DefaultModification(modOp, ldapAttributeType.getName()));
} else {
// Do NOT set AttributeType here
// The attributeType might not match the Value class
// e.g. human-readable jpegPhoto attribute will expect StringValue
DefaultAttribute ldapAttribute = new DefaultAttribute(ldapAttributeType.getName(), ldapValues.toArray(new Value[ldapValues.size()]));
ldapModifications.add(new DefaultModification(modOp, ldapAttribute));
}
}
/**
* For poly attributes, such as language tags.
*/
private void addLdapModificationPoly(Dn dn, List<Modification> ldapModifications,
ModificationOperation modOp, AttributeType ldapAttributeType, List<Object> connIdValues) {
// Add modifications for values that are in the input polystring
// Map key: option(language tag or null), value: LDAP value
Map<String,List<Value>> ldapValueMap = schemaTranslator.toLdapPolyValues(ldapAttributeType, connIdValues);
for (Map.Entry<String, List<Value>> valueMapEntry : ldapValueMap.entrySet()) {
// Do NOT set AttributeType here
// The attributeType might not match the Value class
// e.g. human-readable jpegPhoto attribute will expect StringValue
DefaultAttribute ldapAttribute = new DefaultAttribute(valueMapEntry.getKey(), valueMapEntry.getValue().toArray(new Value[valueMapEntry.getValue().size()]));
ldapModifications.add(new DefaultModification(modOp, ldapAttribute));
}
// We are going to delete all other existing attributes with options. But to do that, we need to read the entry first.
// Question: how to query only for a single attribute, but with all the options? something like description;*
// For now just query for everything.
Entry existingEntry = searchSingleEntry(connectionManager, dn, null, SearchScope.OBJECT, null /* see above */,
"pre-read of entry to eliminate extra optioned attribute values for attribute "+ldapAttributeType.getName(), null);
LOG.ok("Pre-read entry for {0}:\n{1}", ldapAttributeType.getName(), existingEntry);
if (existingEntry == null) {
// Strange. We are going to modify something that is not there?
throw new UnknownUidException("Cannot pre-read of entry to eliminate extra optioned attribute values for attribute "+ldapAttributeType.getName() + ": "+dn);
} else {
Iterator<org.apache.directory.api.ldap.model.entry.Attribute> iterator = existingEntry.iterator();
while (iterator.hasNext()) {
org.apache.directory.api.ldap.model.entry.Attribute existingLdapAttribute = iterator.next();
String existingLdapAttrName = schemaTranslator.getLdapAttributeName(existingLdapAttribute);
if (!ldapAttributeType.getName().equals(existingLdapAttrName)) {
continue;
}
List<Value> expectedValue = ldapValueMap.get(existingLdapAttribute.getUpId());
if (expectedValue == null) {
// We want this attribute cleared
LOG.ok("Clearing poly attribute {0}", existingLdapAttribute.getUpId());
DefaultAttribute ldapAttribute = new DefaultAttribute(existingLdapAttribute.getUpId() /* no value*/);
ldapModifications.add(new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, ldapAttribute));
}
}
}
}
protected void postUpdate(ObjectClass connIdObjectClass, Uid uid, Set<AttributeDelta> deltas,
OperationOptions options,
Dn dn, org.apache.directory.api.ldap.model.schema.ObjectClass ldapStructuralObjectClass, List<Modification> ldapModifications) {
......@@ -1424,6 +1478,9 @@ public abstract class AbstractLdapConnector<C extends AbstractLdapConfiguration>
LOG.ok("Resolving DN for UID {0}", uid);
Entry entry = searchSingleEntry(getConnectionManager(), baseDn, filterNode, scope,
new String[]{uidAttributeName}, "LDAP entry for UID "+uid, options);
if (entry == null) {
throw new UnknownUidException("LDAP entry for UID " + uid + " was not found");
}
dn = entry.getDn();
}
......@@ -1450,6 +1507,10 @@ public abstract class AbstractLdapConnector<C extends AbstractLdapConfiguration>
SearchScope scope, String[] attributesToGet, String descMessage, Dn dnHint, OperationOptions options) {
LdapNetworkConnection connection = connectionManager.getConnection(dnHint, options);
if (filterNode == null) {
filterNode = LdapUtil.createAllSearchFilter();
}
String filterString = filterNode.toString();
Entry entry = null;
......@@ -1465,7 +1526,9 @@ public abstract class AbstractLdapConnector<C extends AbstractLdapConfiguration>
searchReq.setBase(baseDn);
searchReq.setFilter(filterNode);
searchReq.setScope(scope);
searchReq.addAttributes(attributesToGet);
if (attributesToGet != null) {
searchReq.addAttributes(attributesToGet);
}
searchReq.setDerefAliases(AliasDerefMode.NEVER_DEREF_ALIASES);
SearchCursor cursor = null;
......@@ -1481,8 +1544,8 @@ public abstract class AbstractLdapConnector<C extends AbstractLdapConfiguration>
break;
}
} else {
// Something wrong happened, the entry was not created.
throw new UnknownUidException(descMessage + " was not found");
// Entry is not there.
return null;
}
} catch (CursorLdapReferralException e) {
LOG.ok("Got cursor referral exception while resolving {0}: {1}", descMessage, e.getReferralInfo());
......
......@@ -161,7 +161,7 @@ public class LdapSchemaTranslator extends AbstractSchemaTranslator<LdapConfigura
}
return ldapValueMap;
}
@Override
public AttributeType toLdapAttribute(org.apache.directory.api.ldap.model.schema.ObjectClass ldapObjectClass,
String icfAttributeName) {
......@@ -190,33 +190,15 @@ public class LdapSchemaTranslator extends AbstractSchemaTranslator<LdapConfigura
Map<String,Object> connIdValueMap = new HashMap<>();
for (org.apache.directory.api.ldap.model.entry.Attribute ldapAttribute : ldapAttributes) {
String option = getLdapAttributeOption(ldapAttribute);
if (option != null && !option.startsWith("lang-")) {
LOG.ok("Skipping unknown option {0} on attribute {1}", option, ldapAttributeNameFromSchema);
continue;
}
if (ldapAttribute.size() == 0) {
LOG.ok("Skipping empty attribute {0};{1}", ldapAttributeNameFromSchema, option);
String connIdMapKey = determinePolyKey(ldapAttribute);
if (connIdMapKey == null) {
continue;
}
if (ldapAttribute.size() > 1) {
throw new InvalidAttributeValueException("Multi-valued multi-attributes are not supported, attribute "+ldapAttributeNameFromSchema
+";"+option+" on "+entry.getDn());
}
if (attributeHandler != null) {
attributeHandler.handle(connection, entry, ldapAttribute, ab);
}
String connIdMapKey;
if (option == null) {
connIdMapKey = POLYSTRING_ORIG_KEY;
} else {
connIdMapKey = option.substring("lang-".length());
}
Value ldapValue = ldapAttribute.get();
Object connIdValue = toConnIdValue(connIdAttributeName, ldapValue, ldapAttributeNameFromSchema, ldapAttributeType);
......@@ -233,6 +215,31 @@ public class LdapSchemaTranslator extends AbstractSchemaTranslator<LdapConfigura
throw new IllegalArgumentException(e.getMessage() + ", attribute "+connIdAttributeName+" (ldap: "+ldapAttributeNameFromSchema+")", e);
}
}
@Override
public String determinePolyKey(org.apache.directory.api.ldap.model.entry.Attribute ldapAttribute) {
String option = getLdapAttributeOption(ldapAttribute);
if (option != null && !option.startsWith("lang-")) {
LOG.ok("Unknown option {0} on attribute {1}", option, ldapAttribute.getUpId());
return null;
}
if (ldapAttribute.size() == 0) {
LOG.ok("Empty attribute {0};{1}", ldapAttribute.getUpId(), option);
return null;
}
if (ldapAttribute.size() > 1) {
throw new InvalidAttributeValueException("Multi-valued multi-attributes are not supported, attribute "+ldapAttribute.getUpId()
+";"+option);
}
if (option == null) {
return POLYSTRING_ORIG_KEY;
} else {
return option.substring("lang-".length());
}
}
@Override
protected void extendConnectorObject(ConnectorObjectBuilder cob, Entry entry, String objectClassName) {
......
......@@ -1093,7 +1093,7 @@ public abstract class AbstractSchemaTranslator<C extends AbstractLdapConfigurati
while (iterator.hasNext()) {
org.apache.directory.api.ldap.model.entry.Attribute ldapAttribute = iterator.next();
String ldapAttrName = getLdapAttributeName(ldapAttribute);
LOG.ok("Processing attribute {0} (UP: {1})", ldapAttrName, ldapAttribute.getUpId());
// LOG.ok("Processing attribute {0} (UP: {1})", ldapAttrName, ldapAttribute.getUpId());
if (!shouldTranslateAttribute(ldapAttrName)) {
// LOG.ok("Should not translate attribute {0}, skipping", ldapAttrName);
continue;
......@@ -1122,7 +1122,7 @@ public abstract class AbstractSchemaTranslator<C extends AbstractLdapConfigurati
String connIdAttributeName = toConnIdAttributeName(ldapAttributeNameFromSchema);
// TODO: use version of findAttributeInfo from SchemaUtil
// TODO: use findAttributeInfo from SchemaUtil
AttributeInfo connIdAttributeInfo = findAttributeInfo(connIdStructuralObjectClassInfo, connIdAttributeName);
if (connIdAttributeInfo == null) {
for (ObjectClassInfo icfAuxiliaryObjectClassInfo: connIdAuxiliaryObjectClassInfos) {
......@@ -1144,7 +1144,7 @@ public abstract class AbstractSchemaTranslator<C extends AbstractLdapConfigurati
if (isPolyAttribute(connIdAttributeInfo)) {
// Defer processing poly attributes for later. We do not have all the values yet. Just collect the values now.
// Defer processing of poly attributes for later. We do not have all the values yet. Just collect the values now.
polyAttributes.put(ldapAttributeNameFromSchema, new PolyAttributeStruct(ldapAttributeType, connIdAttributeName, ldapAttribute));
} else {
......@@ -1266,6 +1266,10 @@ public abstract class AbstractSchemaTranslator<C extends AbstractLdapConfigurati
throw new UnsupportedOperationException("Poly-attributes are not supported (attribute '"+ldapAttributeNameFromSchema+"'");
}
public String determinePolyKey(org.apache.directory.api.ldap.model.entry.Attribute ldapAttribute) {
throw new UnsupportedOperationException("Poly-attributes are not supported");
}
public String getDn(Entry entry) {
return entry.getDn().getName();
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment