[CalendarServer-changes] [7263] CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory .py

source_changes at macosforge.org source_changes at macosforge.org
Fri Mar 25 12:54:31 PDT 2011


Revision: 7263
          http://trac.macosforge.org/projects/calendarserver/changeset/7263
Author:   sagen at apple.com
Date:     2011-03-25 12:54:29 -0700 (Fri, 25 Mar 2011)
Log Message:
-----------
Certain opendirectory.framework error codes necessitate a retry

Modified Paths:
--------------
    CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py

Modified: CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py
===================================================================
--- CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py	2011-03-24 23:03:38 UTC (rev 7262)
+++ CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py	2011-03-25 19:54:29 UTC (rev 7263)
@@ -26,6 +26,17 @@
 
 log = Logger()
 
+NUM_TRIES = 3
+
+RETRY_CODES = (
+    5200, # Server unreachable
+    5201, # Server not found
+    5202, # Server error
+    5203, # Server timeout
+    5204, # Contact master
+    5205, # Server communication error
+)
+
 # Single-value attributes (must be converted from lists):
 SINGLE_VALUE_ATTRIBUTES = [
     dsattributes.kDS1AttrBirthday,
@@ -133,15 +144,28 @@
         C{None} on failure.
     """
     session = odframework.ODSession.defaultSession()
-    node, error = odframework.ODNode.nodeWithSession_name_error_(session,
-        nodeName, None)
-    if error:
-        log.error(error)
-        raise ODError(error)
 
-    return Directory(session, node, nodeName)
+    tries = NUM_TRIES
+    while tries:
+        node, error = odframework.ODNode.nodeWithSession_name_error_(session,
+            nodeName, None)
 
+        if not error:
+            return Directory(session, node, nodeName)
 
+        code = error.code()
+        log.debug("Received code %d from node call: %s" % (code, error))
+
+        if code in RETRY_CODES:
+            tries -= 1
+        else:
+            break
+
+    log.error(error)
+    raise ODError(error)
+
+
+
 def getNodeAttributes(directory, nodeName, attributes):
     """
     Return key attributes for the specified directory node. The attributes
@@ -153,13 +177,26 @@
     @param attributes: C{list} or C{tuple} containing the attributes to return for each record.
     @return: C{dict} of attributes found.
     """
-    details, error = directory.node.nodeDetailsForKeys_error_(attributes, None)
-    if error:
-        log.error(error)
-        raise ODError(error)
-    return details
 
+    tries = NUM_TRIES
+    while tries:
 
+        details, error = directory.node.nodeDetailsForKeys_error_(attributes, None)
+        if not error:
+            return details
+
+        code = error.code()
+        log.debug("Received code %d from node details call: %s" % (code, error))
+
+        if code in RETRY_CODES:
+            tries -= 1
+        else:
+            break
+
+    log.error(error)
+    raise ODError(error)
+
+
 def listAllRecordsWithAttributes_list(directory, recordType, attributes, count=0):
     """
     List records in Open Directory, and return key attributes for each one.
@@ -177,27 +214,37 @@
 
     attributeNames, encodings = attributeNamesFromList(attributes)
 
-    query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
-        directory.node,
-        recordType,
-        None,
-        MATCHANY,
-        None,
-        attributeNames,
-        count,
-        None)
-    if error:
-        log.error(error)
-        raise ODError(error)
-    records, error = query.resultsAllowingPartial_error_(False, None)
-    if error:
-        log.error(error)
-        raise ODError(error)
-    for record in records:
-        results.append(recordToResult(record, encodings))
-    return results
+    tries = NUM_TRIES
+    while tries:
+        query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
+            directory.node,
+            recordType,
+            None,
+            MATCHANY,
+            None,
+            attributeNames,
+            count,
+            None)
 
+        if not error:
+            records, error = query.resultsAllowingPartial_error_(False, None)
 
+        if not error:
+            for record in records:
+                results.append(recordToResult(record, encodings))
+            return results
+
+        code = error.code()
+        log.debug("Received code %d from query call: %s" % (code, error))
+
+        if code in RETRY_CODES:
+            tries -= 1
+        else:
+            break
+
+    log.error(error)
+    raise ODError(error)
+
 def queryRecordsWithAttribute_list(directory, attr, value, matchType, casei, recordType, attributes, count=0):
     """
     List records in Open Directory matching specified attribute/value, and return key attributes for each one.
@@ -220,27 +267,39 @@
 
     attributeNames, encodings = attributeNamesFromList(attributes)
 
-    query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
-        directory.node,
-        recordType,
-        attr,
-        adjustMatchType(matchType, casei),
-        value.decode("utf-8"),
-        attributeNames,
-        count,
-        None)
-    if error:
-        log.error(error)
-        raise ODError(error)
-    records, error = query.resultsAllowingPartial_error_(False, None)
-    if error:
-        log.error(error)
-        raise ODError(error)
-    for record in records:
-        results.append(recordToResult(record, encodings))
-    return results
+    tries = NUM_TRIES
+    while tries:
 
+        query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
+            directory.node,
+            recordType,
+            attr,
+            adjustMatchType(matchType, casei),
+            value.decode("utf-8"),
+            attributeNames,
+            count,
+            None)
 
+        if not error:
+            records, error = query.resultsAllowingPartial_error_(False, None)
+
+        if not error:
+            for record in records:
+                results.append(recordToResult(record, encodings))
+            return results
+
+        code = error.code()
+        log.debug("Received code %d from query call: %s" % (code, error))
+
+        if code in RETRY_CODES:
+            tries -= 1
+        else:
+            break
+
+    log.error(error)
+    raise ODError(error)
+
+
 def queryRecordsWithAttributes_list(directory, compound, casei, recordType, attributes, count=0):
     """
     List records in Open Directory matching specified criteria, and return key attributes for each one.
@@ -260,27 +319,39 @@
 
     attributeNames, encodings = attributeNamesFromList(attributes)
 
-    query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
-        directory.node,
-        recordType,
-        None,
-        0x210B, # adjustMatchType(matchType, casei),
-        compound,
-        attributeNames,
-        count,
-        None)
-    if error:
-        log.error(error)
-        raise ODError(error)
-    records, error = query.resultsAllowingPartial_error_(False, None)
-    if error:
-        log.error(error)
-        raise ODError(error)
-    for record in records:
-        results.append(recordToResult(record, encodings))
-    return results
+    tries = NUM_TRIES
+    while tries:
 
+        query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
+            directory.node,
+            recordType,
+            None,
+            0x210B, # adjustMatchType(matchType, casei),
+            compound,
+            attributeNames,
+            count,
+            None)
 
+        if not error:
+            records, error = query.resultsAllowingPartial_error_(False, None)
+
+        if not error:
+            for record in records:
+                results.append(recordToResult(record, encodings))
+            return results
+
+        code = error.code()
+        log.debug("Received code %d from query call: %s" % (code, error))
+
+        if code in RETRY_CODES:
+            tries -= 1
+        else:
+            break
+
+    log.error(error)
+    raise ODError(error)
+
+
 def getUserRecord(directory, user):
     """
     Look up the record for the given user within the directory's node
@@ -289,17 +360,30 @@
     @param user: C{str} the user identifier/directory record name to fetch.
     @return: OD record if the user was found, None otherwise.
     """
-    record, error = directory.node.recordWithRecordType_name_attributes_error_(
-        dsattributes.kDSStdRecordTypeUsers,
-        user,
-        None,
-        None
-    )
-    if error:
-        log.error(error)
-        raise ODError(error)
-    return record
+    tries = NUM_TRIES
+    while tries:
 
+        record, error = directory.node.recordWithRecordType_name_attributes_error_(
+            dsattributes.kDSStdRecordTypeUsers,
+            user,
+            None,
+            None
+        )
+        if not error:
+            return record
+
+        code = error.code()
+        log.debug("Received code %d from recordWithRecordType call: %s" % (code, error))
+
+        if code in RETRY_CODES:
+            tries -= 1
+        else:
+            break
+
+    log.error(error)
+    raise ODError(error)
+
+
 def authenticateUserBasic(directory, nodeName, user, password):
     """
     Authenticate a user with a password to Open Directory.
@@ -314,13 +398,24 @@
     if record is None:
         raise ODError("Record not found")
 
-    result, error = record.verifyPassword_error_(password, None)
-    if error:
-        log.error(error)
-        raise ODError(error)
-    return result
+    tries = NUM_TRIES
+    while tries:
+        result, error = record.verifyPassword_error_(password, None)
+        if not error:
+            return result
 
+        code = error.code()
+        log.debug("Received code %d from Basic auth call: %s" % (code, error))
 
+        if code in RETRY_CODES:
+            tries -= 1
+        else:
+            break
+
+    log.error(error)
+    raise ODError(error)
+
+
 def authenticateUserDigest(directory, nodeName, user, challenge, response, method):
     """
     Authenticate using HTTP Digest credentials to Open Directory.
@@ -337,19 +432,31 @@
     if record is None:
         raise ODError("Record not found")
 
-    # TODO: what are these other return values?
-    result, mystery1, mystery2, error = record.verifyExtendedWithAuthenticationType_authenticationItems_continueItems_context_error_(
-        DIGEST_MD5,
-        [user, challenge, response, method],
-        None, None, None
-    )
-    if error:
-        log.error(error)
-        raise ODError(error)
-    return result
+    tries = NUM_TRIES
+    while tries:
 
+        # TODO: what are these other return values?
+        result, mystery1, mystery2, error = record.verifyExtendedWithAuthenticationType_authenticationItems_continueItems_context_error_(
+            DIGEST_MD5,
+            [user, challenge, response, method],
+            None, None, None
+        )
+        if not error:
+            return result
+
+        code = error.code()
+        log.debug("Received code %d from Digest auth call: %s" % (code, error))
+
+        if code in RETRY_CODES:
+            tries -= 1
+        else:
+            break
+
+    log.error(error)
+    raise ODError(error)
+
+
 class ODError(Exception):
     """
     Exceptions from DirectoryServices errors.
     """
-    pass
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110325/51c2c4b0/attachment-0001.html>


More information about the calendarserver-changes mailing list