Juan Hernandez has uploaded a new change for review.

Change subject: [WIP] Add temporary LDAP provider
......................................................................

[WIP] Add temporary LDAP provider

This changes adds a new temporary LDAP directory provider intended to
serve as a bridge between the new directory interface introduced in a
previous change and the existing LDAP infrastructure. This bridge will
exist while the LDAP engine is migrated step by step to use the new
interfaces.

Change-Id: Icc290ba20b447a06d2dda24500ae0d828597bcb6
Signed-off-by: Juan Hernandez <[email protected]>
---
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectory.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectoryProvider.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectory.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectoryProvider.java
M 
backend/manager/modules/bll/src/main/resources/META-INF/services/org.ovirt.engine.core.bll.directory.DirectorySpi
5 files changed, 496 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/38/15638/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectory.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectory.java
new file mode 100644
index 0000000..5e2c22e
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectory.java
@@ -0,0 +1,192 @@
+package org.ovirt.engine.core.bll.directory.ldap;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.ovirt.engine.core.bll.QueryData;
+import org.ovirt.engine.core.bll.adbroker.AdActionType;
+import org.ovirt.engine.core.bll.adbroker.LdapBroker;
+import org.ovirt.engine.core.bll.adbroker.LdapFactory;
+import org.ovirt.engine.core.bll.adbroker.LdapQueryData;
+import org.ovirt.engine.core.bll.adbroker.LdapQueryDataImpl;
+import org.ovirt.engine.core.bll.adbroker.LdapQueryType;
+import org.ovirt.engine.core.bll.adbroker.LdapReturnValueBase;
+import org.ovirt.engine.core.bll.adbroker.LdapSearchByIdParameters;
+import org.ovirt.engine.core.bll.adbroker.LdapSearchByQueryParameters;
+import org.ovirt.engine.core.bll.adbroker.LdapSearchByUserIdListParameters;
+import org.ovirt.engine.core.bll.adbroker.LdapSearchByUserNameParameters;
+import org.ovirt.engine.core.common.businessentities.LdapGroup;
+import org.ovirt.engine.core.common.businessentities.LdapUser;
+import org.ovirt.engine.core.common.config.Config;
+import org.ovirt.engine.core.common.config.ConfigValues;
+import 
org.ovirt.engine.core.common.errors.SearchEngineIllegalCharacterException;
+import org.ovirt.engine.core.common.errors.SqlInjectionException;
+import org.ovirt.engine.core.common.users.Directory;
+import org.ovirt.engine.core.common.users.DirectoryGroup;
+import org.ovirt.engine.core.common.users.DirectoryUser;
+import org.ovirt.engine.core.compat.DateTime;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.compat.TimeSpan;
+import org.ovirt.engine.core.searchbackend.ISyntaxChecker;
+import org.ovirt.engine.core.searchbackend.SearchObjects;
+import org.ovirt.engine.core.searchbackend.SyntaxCheckerFactory;
+import org.ovirt.engine.core.searchbackend.SyntaxContainer;
+import org.ovirt.engine.core.searchbackend.SyntaxError;
+
+public class LdapDirectory implements Directory {
+    // The name of the domain:
+    private String domain;
+
+    public LdapDirectory(String domain) {
+        this.domain = domain;
+    }
+
+    @Override
+    public String getName() {
+        return domain;
+    }
+
+    @Override
+    public DirectoryUser findUserById(Guid id) {
+        // Find the user with the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.GetAdUserByUserId,
+            new LdapSearchByIdParameters(domain, id)
+        );
+        LdapUser ldapUser = (LdapUser) ldapResult.getReturnValue();
+
+        // Map the user:
+        return mapUser(ldapUser);
+    }
+
+    @Override
+    public DirectoryUser findUserByName(String name) {
+        // Find the user with the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.GetAdUserByUserName,
+            new LdapSearchByUserNameParameters(null, domain, name)
+        );
+        LdapUser ldapUser = (LdapUser) ldapResult.getReturnValue();
+
+        // Map the user:
+        return mapUser(ldapUser);
+    }
+
+    @Override
+    public Set<DirectoryUser> findUsersById(Set<Guid> ids) {
+        // Find the users using the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.GetAdUserByUserIdList,
+            new LdapSearchByUserIdListParameters(domain, new 
ArrayList<Guid>(ids), false)
+        );
+        List<LdapUser> ldapUsers = (List<LdapUser>) 
ldapResult.getReturnValue();
+
+        // Map the users:
+        return mapUsers(ldapUsers);
+    }
+
+    @Override
+    public Set<DirectoryUser> findUsersByQuery(String query) {
+        // Prepare the query data:
+        QueryData data = initQueryData();
+        LdapQueryData ldapQueryData = new LdapQueryDataImpl();
+        ldapQueryData.setLdapQueryType(LdapQueryType.searchUsers);
+        ldapQueryData.setDomain(domain);
+        ldapQueryData.setFilterParameters(new Object[] { 
data.getQueryForAdBroker() });
+
+        // Find the users using the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.SearchUserByQuery,
+            new LdapSearchByQueryParameters(null, domain, ldapQueryData)
+        );
+        List<LdapUser> ldapUsers = (List<LdapUser>) 
ldapResult.getReturnValue();
+
+        // Map the users:
+        return mapUsers(ldapUsers);
+    }
+
+    private DirectoryUser mapUser(LdapUser ldapUser) {
+        DirectoryUser directoryUser = new DirectoryUser(
+            this,
+            ldapUser.getUserId(),
+            ldapUser.getUserName()
+        );
+        directoryUser.setFirstName(ldapUser.getName());
+        directoryUser.setLastName(ldapUser.getSurName());
+        directoryUser.setDepartment(ldapUser.getDepartment());
+        directoryUser.setEmail(ldapUser.getEmail());
+        directoryUser.setTitle(ldapUser.getTitle());
+        return directoryUser;
+    }
+
+    private Set<DirectoryUser> mapUsers(List<LdapUser> ldapUsers) {
+        Set<DirectoryUser> directoryUsers = new 
HashSet<DirectoryUser>(ldapUsers.size());
+        for (LdapUser ldapUser : ldapUsers) {
+            DirectoryUser directoryUser = mapUser(ldapUser);
+            directoryUsers.add(directoryUser);
+        }
+        return directoryUsers;
+    }
+
+    @Override
+    public DirectoryGroup findGroupById(Guid id) {
+        // Find the group using the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.GetAdGroupByGroupId,
+            new LdapSearchByIdParameters(domain, id)
+        );
+        LdapGroup ldapGroup = (LdapGroup) ldapResult.getReturnValue();
+
+        // Map the group:
+        return mapGroup(ldapGroup);
+    }
+
+    @Override
+    public Set<DirectoryGroup> findGroupsByQuery(String query) {
+        // Prepare the query data:
+        QueryData queryData = initQueryData();
+        LdapQueryData ldapQueryData = new LdapQueryDataImpl();
+        ldapQueryData.setLdapQueryType(LdapQueryType.searchUsers);
+        ldapQueryData.setDomain(domain);
+        ldapQueryData.setFilterParameters(new Object[] { 
data.getQueryForAdBroker() });
+
+        // Find the groups using the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.SearchGroupsByQuery,
+            new LdapSearchByQueryParameters(null, domain, ldapQueryData)
+        );
+        List<LdapGroup> ldapGroups = (List<LdapGroup>) 
ldapResult.getReturnValue();
+
+        // Map the groups:
+        return mapGroups(ldapGroups);
+    }
+
+    private DirectoryGroup mapGroup(LdapGroup ldapGroup) {
+        DirectoryGroup directoryGroup = new DirectoryGroup(
+            this,
+            ldapGroup.getid(),
+            ldapGroup.getname()
+        );
+        return directoryGroup;
+    }
+
+    private Set<DirectoryGroup> mapGroups(List<LdapGroup> ldapGroups) {
+        Set<DirectoryGroup> directoryGroups = new 
HashSet<DirectoryGroup>(ldapGroups.size());
+        for (LdapGroup ldapGroup : ldapGroups) {
+            DirectoryGroup directoryGroup = mapGroup(ldapGroup);
+            directoryGroups.add(directoryGroup);
+        }
+        return directoryGroups;
+    }
+
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectoryProvider.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectoryProvider.java
new file mode 100644
index 0000000..e18dd5d
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectoryProvider.java
@@ -0,0 +1,26 @@
+package org.ovirt.engine.core.bll.directory.ldap;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.ovirt.engine.core.bll.directory.DirectorySpi;
+import org.ovirt.engine.core.common.users.Directory;
+
+public class LdapDirectoryProvider implements DirectorySpi {
+    // The list of directories managed by this implementation (will be lazily
+    // initialized later:
+    private volatile List<Directory> directories;
+
+    @Override
+    public List<Directory> getDirectories() {
+        if (directories == null) {
+            synchronized (LdapDirectoryProvider.class) {
+                if (directories == null) {
+                    Directory directory = new LdapDirectory();
+                    directories = Collections.singletonList(directory);
+                }
+            }
+        }
+        return directories;
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectory.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectory.java
new file mode 100644
index 0000000..1089b4f
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectory.java
@@ -0,0 +1,237 @@
+package org.ovirt.engine.core.bll.directory.ldap;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.ovirt.engine.core.bll.QueryData;
+import org.ovirt.engine.core.bll.adbroker.AdActionType;
+import org.ovirt.engine.core.bll.adbroker.LdapBroker;
+import org.ovirt.engine.core.bll.adbroker.LdapFactory;
+import org.ovirt.engine.core.bll.adbroker.LdapQueryData;
+import org.ovirt.engine.core.bll.adbroker.LdapQueryDataImpl;
+import org.ovirt.engine.core.bll.adbroker.LdapQueryType;
+import org.ovirt.engine.core.bll.adbroker.LdapReturnValueBase;
+import org.ovirt.engine.core.bll.adbroker.LdapSearchByIdParameters;
+import org.ovirt.engine.core.bll.adbroker.LdapSearchByQueryParameters;
+import org.ovirt.engine.core.bll.adbroker.LdapSearchByUserIdListParameters;
+import org.ovirt.engine.core.bll.adbroker.LdapSearchByUserNameParameters;
+import org.ovirt.engine.core.bll.directory.DirectoryManager;
+import org.ovirt.engine.core.common.businessentities.LdapGroup;
+import org.ovirt.engine.core.common.businessentities.LdapUser;
+import org.ovirt.engine.core.common.users.Directory;
+import org.ovirt.engine.core.common.users.DirectoryGroup;
+import org.ovirt.engine.core.common.users.DirectoryUser;
+import org.ovirt.engine.core.compat.Guid;
+
+/**
+ * This directory implementation is a bridge between the new directory
+ * interface and the existing LDAP infrastructure. It will exist only while the
+ * engine is migrated to use the new directory interface, then it will be
+ * removed.
+ */
+public class ProvisionalLdapDirectory implements Directory {
+    // The log:
+    private Logger log = Logger.getLogger(ProvisionalLdapDirectory.class);
+
+    // The name of the domain:
+    private String domain;
+
+    public ProvisionalLdapDirectory(String domain) {
+        this.domain = domain;
+    }
+
+    @Override
+    public String getName() {
+        return domain;
+    }
+
+    @Override
+    public DirectoryUser findUserById(Guid id) {
+        // Find the user with the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.GetAdUserByUserId,
+            new LdapSearchByIdParameters(domain, id)
+        );
+        LdapUser ldapUser = (LdapUser) ldapResult.getReturnValue();
+
+        // Map the user:
+        return mapUser(ldapUser);
+    }
+
+    @Override
+    public DirectoryUser findUserByName(String name) {
+        // Find the user with the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.GetAdUserByUserName,
+            new LdapSearchByUserNameParameters(null, domain, name)
+        );
+        LdapUser ldapUser = (LdapUser) ldapResult.getReturnValue();
+
+        // Map the user:
+        return mapUser(ldapUser);
+    }
+
+    @Override
+    public Set<DirectoryUser> findUsersById(Set<Guid> ids) {
+        // Find the users using the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.GetAdUserByUserIdList,
+            new LdapSearchByUserIdListParameters(domain, new 
ArrayList<Guid>(ids), false)
+        );
+        @SuppressWarnings("unchecked")
+        List<LdapUser> ldapUsers = (List<LdapUser>) 
ldapResult.getReturnValue();
+
+        // Map the users:
+        return mapUsers(ldapUsers);
+    }
+
+    @Override
+    public Set<DirectoryUser> findUsersByQuery(String query) {
+        // Prepare the query data:
+        QueryData queryData = parseQuery();
+        LdapQueryData ldapQueryData = new LdapQueryDataImpl();
+        ldapQueryData.setLdapQueryType(LdapQueryType.searchUsers);
+        ldapQueryData.setDomain(domain);
+        ldapQueryData.setFilterParameters(new Object[] { 
queryData.getQueryForAdBroker() });
+
+        // Find the users using the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.SearchUserByQuery,
+            new LdapSearchByQueryParameters(null, domain, ldapQueryData)
+        );
+        @SuppressWarnings("unchecked")
+        List<LdapUser> ldapUsers = (List<LdapUser>) 
ldapResult.getReturnValue();
+
+        // Map the users:
+        return mapUsers(ldapUsers);
+    }
+
+    /**
+     * Transforms a LDAP user into a directory user.
+     */
+    private DirectoryUser mapUser(LdapUser ldapUser) {
+        // Create the directory user and populate the basic attributes:
+        DirectoryUser directoryUser = new DirectoryUser(
+            this,
+            ldapUser.getUserId(),
+            ldapUser.getUserName()
+        );
+        directoryUser.setFirstName(ldapUser.getName());
+        directoryUser.setLastName(ldapUser.getSurName());
+        directoryUser.setDepartment(ldapUser.getDepartment());
+        directoryUser.setEmail(ldapUser.getEmail());
+        directoryUser.setTitle(ldapUser.getTitle());
+
+        // Populate the groups of the user (note that as we a calling a method
+        // of this directory to do so we should first locate it using the,
+        // calling the method directory would bypass any decorator that may
+        // put on top of the directory):
+        Directory directory = 
DirectoryManager.getInstance().getDirectory(domain);
+        if (directory == null) {
+            log.warn(
+                "Can't find directory \"" + domain + "\" to retrieve groups " +
+                "for user \"" + directoryUser.getId() + "\", the groups and " +
+                "related permissions won't be available."
+            );
+        }
+        else {
+            String[] ids = ldapUser.getGroupIds().split(",");
+            List<DirectoryGroup> directoryGroups = new 
ArrayList<DirectoryGroup>(ids.length);
+            for (String id : ids) {
+                DirectoryGroup directoryGroup = 
findGroupById(Guid.createGuidFromString(id));
+                if (directoryGroup != null) {
+                    directoryGroups.add(directoryGroup);
+                }
+            }
+            directoryUser.setGroups(directoryGroups);
+        }
+
+        return directoryUser;
+    }
+
+    /**
+     * Transforms a list of LDAP users into a list of directory users.
+     */
+    private Set<DirectoryUser> mapUsers(List<LdapUser> ldapUsers) {
+        Set<DirectoryUser> directoryUsers = new 
HashSet<DirectoryUser>(ldapUsers.size());
+        for (LdapUser ldapUser : ldapUsers) {
+            DirectoryUser directoryUser = mapUser(ldapUser);
+            directoryUsers.add(directoryUser);
+        }
+        return directoryUsers;
+    }
+
+    @Override
+    public DirectoryGroup findGroupById(Guid id) {
+        // Find the group using the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.GetAdGroupByGroupId,
+            new LdapSearchByIdParameters(domain, id)
+        );
+        LdapGroup ldapGroup = (LdapGroup) ldapResult.getReturnValue();
+
+        // Map the group:
+        return mapGroup(ldapGroup);
+    }
+
+    @Override
+    public Set<DirectoryGroup> findGroupsByQuery(String query) {
+        // Prepare the query data:
+        QueryData queryData = parseQuery();
+        LdapQueryData ldapQueryData = new LdapQueryDataImpl();
+        ldapQueryData.setLdapQueryType(LdapQueryType.searchUsers);
+        ldapQueryData.setDomain(domain);
+        ldapQueryData.setFilterParameters(new Object[] { 
queryData.getQueryForAdBroker() });
+
+        // Find the groups using the old mechanism:
+        LdapBroker ldapBroker = LdapFactory.getInstance(domain);
+        LdapReturnValueBase ldapResult = ldapBroker.RunAdAction(
+            AdActionType.SearchGroupsByQuery,
+            new LdapSearchByQueryParameters(null, domain, ldapQueryData)
+        );
+        @SuppressWarnings("unchecked")
+        List<LdapGroup> ldapGroups = (List<LdapGroup>) 
ldapResult.getReturnValue();
+
+        // Map the groups:
+        return mapGroups(ldapGroups);
+    }
+
+    /**
+     * Transforms a LDAP group into a directory group.
+     */
+    private DirectoryGroup mapGroup(LdapGroup ldapGroup) {
+        DirectoryGroup directoryGroup = new DirectoryGroup(
+            this,
+            ldapGroup.getid(),
+            ldapGroup.getname()
+        );
+        return directoryGroup;
+    }
+
+    /**
+     * Transforms a list of LDAP groups into a list of directory groups.
+     */
+    private Set<DirectoryGroup> mapGroups(List<LdapGroup> ldapGroups) {
+        Set<DirectoryGroup> directoryGroups = new 
HashSet<DirectoryGroup>(ldapGroups.size());
+        for (LdapGroup ldapGroup : ldapGroups) {
+            DirectoryGroup directoryGroup = mapGroup(ldapGroup);
+            directoryGroups.add(directoryGroup);
+        }
+        return directoryGroups;
+    }
+
+    // XXX: This method is not implemented yet, we will need to move or copy
+    // here part of the code in the SearchQuery.initQueryData method:
+    private QueryData parseQuery() {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectoryProvider.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectoryProvider.java
new file mode 100644
index 0000000..b8194f9
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectoryProvider.java
@@ -0,0 +1,40 @@
+package org.ovirt.engine.core.bll.directory.ldap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.ovirt.engine.core.bll.adbroker.LdapBrokerUtils;
+import org.ovirt.engine.core.bll.directory.DirectorySpi;
+import org.ovirt.engine.core.common.users.Directory;
+
+public class ProvisionalLdapDirectoryProvider implements DirectorySpi {
+    // The list of directories managed by this implementation (will be lazily
+    // initialized later:
+    private volatile List<Directory> directories;
+
+    @Override
+    public List<Directory> getDirectories() {
+        if (directories == null) {
+            synchronized (ProvisionalLdapDirectoryProvider.class) {
+                if (directories == null) {
+                    directories = loadDirectories();
+                }
+            }
+        }
+        return directories;
+    }
+
+    /**
+     * Get the list of domains using the old mechanism, excluding the internal
+     * domain, then create an implementation for each one.
+     */
+    private List<Directory> loadDirectories() {
+        List<String> domains = LdapBrokerUtils.getDomainsList(true);
+        List<Directory> result = new ArrayList<Directory>(domains.size());
+        for (String domain : domains) {
+            ProvisionalLdapDirectory directory = new 
ProvisionalLdapDirectory(domain);
+            result.add(directory);
+        }
+        return result;
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/resources/META-INF/services/org.ovirt.engine.core.bll.directory.DirectorySpi
 
b/backend/manager/modules/bll/src/main/resources/META-INF/services/org.ovirt.engine.core.bll.directory.DirectorySpi
index 602ccf3..36e2dd3 100644
--- 
a/backend/manager/modules/bll/src/main/resources/META-INF/services/org.ovirt.engine.core.bll.directory.DirectorySpi
+++ 
b/backend/manager/modules/bll/src/main/resources/META-INF/services/org.ovirt.engine.core.bll.directory.DirectorySpi
@@ -1 +1,2 @@
 org.ovirt.engine.core.bll.directory.internal.InternalDirectoryProvider
+org.ovirt.engine.core.bll.directory.ldap.ProvisionalLdapDirectoryProvider


-- 
To view, visit http://gerrit.ovirt.org/15638
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Icc290ba20b447a06d2dda24500ae0d828597bcb6
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Juan Hernandez <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to