Loading of the schema is now performed in the first request that requires it.

https://fedorahosted.org/freeipa/ticket/583

Jan
From 0b1368442254cb738a95e766539fa030fe2504c8 Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzel...@redhat.com>
Date: Tue, 15 Feb 2011 09:37:58 +0100
Subject: [PATCH] Don't load the LDAP schema during startup

https://fedorahosted.org/freeipa/ticket/583
---
 ipalib/plugins/baseldap.py |    6 ++++-
 ipaserver/plugins/ldap2.py |   49 ++++++++++++++++++++++++-------------------
 2 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 6817af413c9c4e4ebf951e933e66449343a7d50a..a3e341172a4cf9c1e861b96b26c2151bcfe93ac0 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -379,7 +379,11 @@ class LDAPObject(Object):
         objectclasses += self.possible_objectclasses
         # Get list of available attributes for this object for use
         # in the ACI UI.
-        attrs = self.api.Backend.ldap2.schema.attribute_types(objectclasses)
+        schema = self.api.Backend.ldap2.get_schema()
+        if not schema:
+            attrs = []
+        else:
+            attrs = schema.attribute_types(objectclasses)
         attrlist = []
         # Go through the MUST first
         for (oid, attr) in attrs[0].iteritems():
diff --git a/ipaserver/plugins/ldap2.py b/ipaserver/plugins/ldap2.py
index b03c8def7416780a6dedf2a0d48358ec09ef9da3..9c689633b879072824dbb4729a89dbc5da3575cb 100644
--- a/ipaserver/plugins/ldap2.py
+++ b/ipaserver/plugins/ldap2.py
@@ -183,12 +183,6 @@ def get_schema(url, conn=None):
 
     return _ldap.schema.SubSchema(schema_entry[1])
 
-# cache schema when importing module
-try:
-    _schema = get_schema(api.env.ldap_uri)
-except AttributeError:
-    _schema = None
-
 # The UPG setting will be cached the first time a module checks it
 _upg = None
 
@@ -228,7 +222,6 @@ class ldap2(CrudBackend, Encoder):
 
     def __init__(self, shared_instance=True, ldap_uri=None, base_dn=None,
                  schema=None):
-        global _schema
         CrudBackend.__init__(self, shared_instance=shared_instance)
         Encoder.__init__(self)
         self.encoder_settings.encode_dict_keys = True
@@ -248,7 +241,7 @@ class ldap2(CrudBackend, Encoder):
                 self.base_dn = api.env.basedn
         except AttributeError:
             self.base_dn = ''
-        self.schema = schema or _schema
+        self.schema = schema
 
     def __del__(self):
         if self.isconnected():
@@ -259,7 +252,9 @@ class ldap2(CrudBackend, Encoder):
 
     def get_syntax(self, attr, value):
         if not self.schema:
-            return None
+            self.schema = get_schema(self.ldap_uri, self.conn)
+            if not self.schema:
+                return None
         obj = self.schema.get_obj(_ldap.schema.AttributeType, attr)
         if obj is not None:
             return obj.syntax
@@ -268,7 +263,9 @@ class ldap2(CrudBackend, Encoder):
 
     def get_allowed_attributes(self, objectclasses):
         if not self.schema:
-            return []
+            self.schema = get_schema(self.ldap_uri, self.conn)
+            if not self.schema:
+                return []
         allowed_attributes = []
         for oc in objectclasses:
             obj = self.schema.get_obj(_ldap.schema.ObjectClass, oc)
@@ -285,10 +282,13 @@ class ldap2(CrudBackend, Encoder):
         If there is a problem loading the schema or the attribute is
         not in the schema return None
         """
-        if self.schema:
-            obj = self.schema.get_obj(_ldap.schema.AttributeType, attr)
-            return obj and obj.single_value
-        return None
+        if not self.schema:
+            self.schema = get_schema(self.ldap_uri, self.conn)
+            if not self.schema:
+                return None
+
+        obj = self.schema.get_obj(_ldap.schema.AttributeType, attr)
+        return obj and obj.single_value
 
     @encode_args(2, 3, 'bind_dn', 'bind_pw')
     def create_connection(self, ccache=None, bind_dn='', bind_pw='',
@@ -309,7 +309,6 @@ class ldap2(CrudBackend, Encoder):
 
         Extends backend.Connectible.create_connection.
         """
-        global _schema
         if tls_cacertfile is not None:
             _ldap.set_option(_ldap.OPT_X_TLS_CACERTFILE, tls_cacertfile)
         if tls_certfile is not None:
@@ -334,10 +333,10 @@ class ldap2(CrudBackend, Encoder):
         except _ldap.LDAPError, e:
             _handle_errors(e, **{})
 
-        if self.schema is None and _schema is None:
-            # explicitly use setattr here so the schema can be set after
-            # the object is finalized.
-            object.__setattr__(self, 'schema', get_schema(self.ldap_uri, conn))
+        # For now let's say the schema is None (will be loaded later)
+        # - explicitly use setattr here so the schema can be set after
+        #   the object is finalized.
+        object.__setattr__(self, 'schema', None)
         return conn
 
     def destroy_connection(self):
@@ -628,9 +627,15 @@ class ldap2(CrudBackend, Encoder):
                 config_entry[a] = self.config_defaults[a]
         return (cdn, config_entry)
 
-    def get_schema(self):
-        """Returns a copy of the current LDAP schema."""
-        return copy.deepcopy(self.schema)
+    def get_schema(self, deepcopy=False):
+        """ Returns either a reference to current schema or its deep copy """
+        if not self.schema:
+            self.schema = get_schema(self.ldap_uri, self.conn)
+
+        if (deepcopy):
+            return copy.deepcopy(self.schema)
+        else:
+            return self.schema
 
     def has_upg(self):
         """Returns True/False whether User-Private Groups are enabled.
-- 
1.7.3.4

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to