<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[14086] CalendarServer/trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.calendarserver.org//changeset/14086">14086</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2014-10-17 11:24:45 -0700 (Fri, 17 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>More cross-pod delegate support: fixing testpods script, re-factoring store/directory setup.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunkbintestpods">CalendarServer/trunk/bin/testpods</a></li>
<li><a href="#CalendarServertrunkcalendarservertapcaldavpy">CalendarServer/trunk/calendarserver/tap/caldav.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertaputilpy">CalendarServer/trunk/calendarserver/tap/util.py</a></li>
<li><a href="#CalendarServertrunkconfcaldavdtestpodAplist">CalendarServer/trunk/conf/caldavd-test-podA.plist</a></li>
<li><a href="#CalendarServertrunkconfcaldavdtestpodBplist">CalendarServer/trunk/conf/caldavd-test-podB.plist</a></li>
<li><a href="#CalendarServertrunktxdavdpsserverpy">CalendarServer/trunk/txdav/dps/server.py</a></li>
<li><a href="#CalendarServertrunktxdavwhodelegatespy">CalendarServer/trunk/txdav/who/delegates.py</a></li>
<li><a href="#CalendarServertrunktxdavwhotesttest_utilpy">CalendarServer/trunk/txdav/who/test/test_util.py</a></li>
<li><a href="#CalendarServertrunktxdavwhoutilpy">CalendarServer/trunk/txdav/who/util.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunkbintestpods"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/bin/testpods (14085 => 14086)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/bin/testpods        2014-10-17 17:22:48 UTC (rev 14085)
+++ CalendarServer/trunk/bin/testpods        2014-10-17 18:24:45 UTC (rev 14086)
</span><span class="lines">@@ -117,8 +117,8 @@
</span><span class="cx"> # Modify the plists
</span><span class="cx"> 
</span><span class="cx"> python -c &quot;import plistlib; f=plistlib.readPlist('${configdir}/caldavd-cdt.plist'); f['ConfigRoot'] = '${configdir}'; f['RunRoot'] = 'Run'; f['Authentication']['Kerberos']['Enabled'] = False; plistlib.writePlist(f, '${configdir}/caldavd-cdt.plist');&quot;
</span><del>-python -c &quot;import plistlib; f=plistlib.readPlist('${configdir}/caldavd-cdt-podA.plist'); f['ImportConfig'] = '${configdir}/caldavd-cdt.plist'; f['ServerRoot'] = '${serverrootA}'; f['ProxyLoadFromFile'] = '${configdir}/auth/proxies-cdt.xml'; f['ResourceService']['params']['xmlFile'] = '${configdir}/auth/resources-cdt.xml'; f['DirectoryService']['params']['xmlFile'] = '${configdir}/auth/accounts-cdt.xml'; f['AugmentService']['params']['xmlFiles'] = ['${configdir}/auth/augments-cdt.xml']; plistlib.writePlist(f, '${configdir}/caldavd-cdt-podA.plist');&quot;
-python -c &quot;import plistlib; f=plistlib.readPlist('${configdir}/caldavd-cdt-podB.plist'); f['ImportConfig'] = '${configdir}/caldavd-cdt.plist'; f['ServerRoot'] = '${serverrootB}'; f['ProxyLoadFromFile'] = '${configdir}/auth/proxies-cdt.xml'; f['ResourceService']['params']['xmlFile'] = '${configdir}/auth/resources-cdt.xml'; f['DirectoryService']['params']['xmlFile'] = '${configdir}/auth/accounts-cdt.xml'; f['AugmentService']['params']['xmlFiles'] = ['${configdir}/auth/augments-cdt.xml']; plistlib.writePlist(f, '${configdir}/caldavd-cdt-podB.plist');&quot;
</del><ins>+python -c &quot;import plistlib; f=plistlib.readPlist('${configdir}/caldavd-cdt-podA.plist'); f['ImportConfig'] = '${configdir}/caldavd-cdt.plist'; f['ServerRoot'] = '${serverrootA}'; f['ConfigRoot'] = '${configdir}'; f['ProxyLoadFromFile'] = '${configdir}/auth/proxies-cdt.xml'; f['ResourceService']['params']['xmlFile'] = '${configdir}/auth/resources-cdt.xml'; f['DirectoryService']['params']['xmlFile'] = '${configdir}/auth/accounts-cdt.xml'; f['AugmentService']['params']['xmlFiles'] = ['${configdir}/auth/augments-cdt.xml']; plistlib.writePlist(f, '${configdir}/caldavd-cdt-podA.plist');&quot;
+python -c &quot;import plistlib; f=plistlib.readPlist('${configdir}/caldavd-cdt-podB.plist'); f['ImportConfig'] = '${configdir}/caldavd-cdt.plist'; f['ServerRoot'] = '${serverrootB}'; f['ConfigRoot'] = '${configdir}'; f['ProxyLoadFromFile'] = '${configdir}/auth/proxies-cdt.xml'; f['ResourceService']['params']['xmlFile'] = '${configdir}/auth/resources-cdt.xml'; f['DirectoryService']['params']['xmlFile'] = '${configdir}/auth/accounts-cdt.xml'; f['AugmentService']['params']['xmlFiles'] = ['${configdir}/auth/augments-cdt.xml']; plistlib.writePlist(f, '${configdir}/caldavd-cdt-podB.plist');&quot;
</ins><span class="cx"> 
</span><span class="cx"> runpod() {
</span><span class="cx">         local podsuffix=&quot;$1&quot;; shift;
</span><span class="lines">@@ -153,6 +153,7 @@
</span><span class="cx"> 
</span><span class="cx"> # Run CDT
</span><span class="cx"> 
</span><ins>+echo &quot;&quot;
</ins><span class="cx"> echo &quot;Starting CDT run&quot;
</span><span class="cx"> 
</span><span class="cx"> cd &quot;${cdt}&quot; &amp;&amp; &quot;${python}&quot; testcaldav.py ${random} ${seed} ${ssl} ${cdtdebug} --print-details-onfail ${printres} -s &quot;${serverinfo}&quot; -x scripts/tests-pod ${subdir} &quot;$@&quot;;
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertapcaldavpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tap/caldav.py (14085 => 14086)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tap/caldav.py        2014-10-17 17:22:48 UTC (rev 14085)
+++ CalendarServer/trunk/calendarserver/tap/caldav.py        2014-10-17 18:24:45 UTC (rev 14086)
</span><span class="lines">@@ -82,9 +82,6 @@
</span><span class="cx"> 
</span><span class="cx"> from txdav.caldav.datastore.scheduling.imip.inbound import MailRetriever
</span><span class="cx"> from txdav.caldav.datastore.scheduling.imip.inbound import scheduleNextMailPoll
</span><del>-from txdav.caldav.datastore.scheduling.ischedule.localservers import (
-    buildServersDB
-)
</del><span class="cx"> from txdav.common.datastore.upgrade.migrate import UpgradeToDatabaseStep
</span><span class="cx"> from txdav.common.datastore.upgrade.sql.upgrade import (
</span><span class="cx">     UpgradeDatabaseCalendarDataStep, UpgradeDatabaseOtherStep,
</span><span class="lines">@@ -94,10 +91,7 @@
</span><span class="cx"> )
</span><span class="cx"> from txdav.common.datastore.work.inbox_cleanup import InboxCleanupWork
</span><span class="cx"> from txdav.common.datastore.work.revision_cleanup import FindMinValidRevisionWork
</span><del>-from txdav.dps.client import DirectoryService as DirectoryProxyClientService
-from txdav.who.cache import CachingDirectoryService
</del><span class="cx"> from txdav.who.groups import GroupCacher
</span><del>-from txdav.who.util import directoryFromConfig
</del><span class="cx"> 
</span><span class="cx"> from twistedcaldav import memcachepool
</span><span class="cx"> from twistedcaldav.config import ConfigurationError
</span><span class="lines">@@ -127,7 +121,8 @@
</span><span class="cx">     checkDirectories, getRootResource,
</span><span class="cx">     oracleConnectorFromConfig, pgConnectorFromConfig,
</span><span class="cx">     pgServiceFromConfig, getDBPool, MemoryLimitService,
</span><del>-    storeFromConfig, getSSLPassphrase, preFlightChecks
</del><ins>+    storeFromConfig, getSSLPassphrase, preFlightChecks,
+    storeFromConfigWithDPSClient, storeFromConfigWithoutDPS,
</ins><span class="cx"> )
</span><span class="cx"> try:
</span><span class="cx">     from calendarserver.version import version
</span><span class="lines">@@ -846,15 +841,8 @@
</span><span class="cx">         CalDAV and CardDAV requests.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         pool, txnFactory = getDBPool(config)
</span><del>-        directory = DirectoryProxyClientService(config.DirectoryRealmName)
-        if config.Servers.Enabled:
-            directory.setServersDB(buildServersDB(config.Servers.MaxClients))
-        if config.DirectoryProxy.InProcessCachingSeconds:
-            directory = CachingDirectoryService(
-                directory,
-                expireSeconds=config.DirectoryProxy.InProcessCachingSeconds
-            )
-        store = storeFromConfig(config, txnFactory, directory)
</del><ins>+        store = storeFromConfigWithDPSClient(config, txnFactory)
+        directory = store.directoryService()
</ins><span class="cx">         logObserver = AMPCommonAccessLoggingObserver()
</span><span class="cx">         result = self.requestProcessingService(options, store, logObserver)
</span><span class="cx"> 
</span><span class="lines">@@ -1380,7 +1368,7 @@
</span><span class="cx">                 Popen(memcachedArgv)
</span><span class="cx"> 
</span><span class="cx">         return self.storageService(
</span><del>-            slaveSvcCreator, logObserver, uid=uid, gid=gid, directory=None
</del><ins>+            slaveSvcCreator, logObserver, uid=uid, gid=gid
</ins><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1397,7 +1385,7 @@
</span><span class="cx"> 
</span><span class="cx">         uid, gid = getSystemIDs(config.UserName, config.GroupName)
</span><span class="cx">         return self.storageService(
</span><del>-            toolServiceCreator, None, uid=uid, gid=gid, directory=None
</del><ins>+            toolServiceCreator, None, uid=uid, gid=gid
</ins><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1448,7 +1436,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def storageService(
</span><del>-        self, createMainService, logObserver, uid=None, gid=None, directory=None
</del><ins>+        self, createMainService, logObserver, uid=None, gid=None
</ins><span class="cx">     ):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         If necessary, create a service to be started used for storage; for
</span><span class="lines">@@ -1492,23 +1480,7 @@
</span><span class="cx">                     maxConnections=config.MaxDBConnectionsPerPool
</span><span class="cx">                 )
</span><span class="cx">                 cp.setServiceParent(ms)
</span><del>-                store = storeFromConfig(config, cp.connection, directory)
-                if directory is None:
-                    # Create a Directory Proxy &quot;Server&quot; service and hand it to
-                    # the store.
-                    if config.Servers.Enabled:
-                        serversDB = buildServersDB(config.Servers.MaxClients)
-                    else:
-                        serversDB = None
-                    directorySvc = directoryFromConfig(
-                        config, store=store, serversDB=serversDB
-                    )
-                    if config.DirectoryProxy.InProcessCachingSeconds:
-                        directorySvc = CachingDirectoryService(
-                            directorySvc,
-                            expireSeconds=config.DirectoryProxy.InProcessCachingSeconds
-                        )
-                    store.setDirectoryService(directorySvc)
</del><ins>+                store = storeFromConfigWithoutDPS(config, cp.connection)
</ins><span class="cx"> 
</span><span class="cx">                 pps = PreProcessingService(
</span><span class="cx">                     createMainService, cp, store, logObserver, storageService
</span><span class="lines">@@ -1625,7 +1597,7 @@
</span><span class="cx">                     &quot;Unknown database type {}&quot;.format(config.DBType)
</span><span class="cx">                 )
</span><span class="cx">         else:
</span><del>-            store = storeFromConfig(config, None, directory)
</del><ins>+            store = storeFromConfig(config, None, None)
</ins><span class="cx">             return createMainService(None, store, logObserver, None)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1920,15 +1892,8 @@
</span><span class="cx"> 
</span><span class="cx">             return multi
</span><span class="cx"> 
</span><del>-        # The master will use its own directory.  We could switch this
-        # service out for a DirectoryProxyClientService once the DPS
-        # sidecar is running, but not sure that's necessary as the master
-        # is likely not doing much directory-related activity once it
-        # spawns the caldavd workers.
-        directory = None
-
</del><span class="cx">         ssvc = self.storageService(
</span><del>-            spawnerSvcCreator, None, uid, gid, directory=directory
</del><ins>+            spawnerSvcCreator, None, uid, gid
</ins><span class="cx">         )
</span><span class="cx">         ssvc.setServiceParent(s)
</span><span class="cx">         return s
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertaputilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tap/util.py (14085 => 14086)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tap/util.py        2014-10-17 17:22:48 UTC (rev 14085)
+++ CalendarServer/trunk/calendarserver/tap/util.py        2014-10-17 18:24:45 UTC (rev 14086)
</span><span class="lines">@@ -28,39 +28,40 @@
</span><span class="cx">     &quot;preFlightChecks&quot;,
</span><span class="cx"> ]
</span><span class="cx"> 
</span><del>-import errno
-import OpenSSL
-import os
-import psutil
</del><ins>+from calendarserver.accesslog import DirectoryLogWrapperResource
+from calendarserver.provision.root import RootResource
+from calendarserver.push.applepush import APNSubscriptionResource
+from calendarserver.push.notifier import NotifierFactory
+from calendarserver.tools.util import checkDirectory
+from calendarserver.webadmin.landing import WebAdminLandingResource
+from calendarserver.webcal.resource import WebCalendarResource
+
</ins><span class="cx"> from socket import fromfd, AF_UNIX, SOCK_STREAM, socketpair
</span><span class="cx"> from subprocess import Popen, PIPE
</span><del>-import sys
</del><span class="cx"> 
</span><del>-
</del><ins>+from twext.enterprise.adbapi2 import ConnectionPool, ConnectionPoolConnection
+from twext.enterprise.adbapi2 import ConnectionPoolClient
+from twext.enterprise.ienterprise import ORACLE_DIALECT
+from twext.enterprise.ienterprise import POSTGRES_DIALECT
</ins><span class="cx"> from twext.internet.ssl import ChainingOpenSSLContextFactory
</span><ins>+from twext.python.filepath import CachingFilePath
</ins><span class="cx"> from twext.python.filepath import CachingFilePath as FilePath
</span><span class="cx"> from twext.python.log import Logger
</span><del>-from txweb2.auth.basic import BasicCredentialFactory
-from txweb2.dav import auth
-from txweb2.dav.util import joinURL
-from txweb2.http_headers import Headers
-from txweb2.resource import Resource
-from txweb2.static import File as FileResource
</del><ins>+from twext.who.checker import HTTPDigestCredentialChecker
+from twext.who.checker import UsernamePasswordCredentialChecker
</ins><span class="cx"> 
</span><span class="cx"> from twisted.application.service import Service
</span><ins>+from twisted.cred.error import UnauthorizedLogin
</ins><span class="cx"> from twisted.cred.portal import Portal
</span><ins>+from twisted.internet import reactor as _reactor
</ins><span class="cx"> from twisted.internet.defer import inlineCallbacks, returnValue, Deferred, succeed
</span><del>-from twisted.internet import reactor as _reactor
</del><span class="cx"> from twisted.internet.reactor import addSystemEventTrigger
</span><span class="cx"> from twisted.internet.tcp import Connection
</span><ins>+from twisted.python.usage import UsageError
</ins><span class="cx"> 
</span><del>-from calendarserver.push.applepush import APNSubscriptionResource
-from calendarserver.push.notifier import NotifierFactory
-from twext.enterprise.adbapi2 import ConnectionPool, ConnectionPoolConnection
-from twext.enterprise.ienterprise import ORACLE_DIALECT
-from twext.enterprise.ienterprise import POSTGRES_DIALECT
</del><span class="cx"> from twistedcaldav.bind import doBind
</span><span class="cx"> from twistedcaldav.cache import CacheStoreNotifierFactory
</span><ins>+from twistedcaldav.config import ConfigurationError
</ins><span class="cx"> from twistedcaldav.controlapi import ControlAPIResource
</span><span class="cx"> from twistedcaldav.directory.addressbook import DirectoryAddressBookHomeProvisioningResource
</span><span class="cx"> from twistedcaldav.directory.calendar import DirectoryCalendarHomeProvisioningResource
</span><span class="lines">@@ -69,48 +70,48 @@
</span><span class="cx"> from twistedcaldav.directorybackedaddressbook import DirectoryBackedAddressBookResource
</span><span class="cx"> from twistedcaldav.resource import AuthenticationWrapper
</span><span class="cx"> from twistedcaldav.simpleresource import SimpleResource, SimpleRedirectResource
</span><ins>+from twistedcaldav.stdconfig import config
</ins><span class="cx"> from twistedcaldav.timezones import TimezoneCache
</span><span class="cx"> from twistedcaldav.timezoneservice import TimezoneServiceResource
</span><span class="cx"> from twistedcaldav.timezonestdservice import TimezoneStdServiceResource
</span><del>-from txdav.caldav.datastore.scheduling.ischedule.dkim import DKIMUtils, DomainKeyResource
-from txdav.caldav.datastore.scheduling.ischedule.resource import IScheduleInboxResource
</del><span class="cx"> 
</span><del>-
-try:
-    from twistedcaldav.authkerb import NegotiateCredentialFactory
-    NegotiateCredentialFactory  # pacify pyflakes
-except ImportError:
-    NegotiateCredentialFactory = None
-
-from twext.enterprise.adbapi2 import ConnectionPoolClient
</del><span class="cx"> from txdav.base.datastore.dbapiclient import DBAPIConnector, OracleConnector
</span><span class="cx"> from txdav.base.datastore.dbapiclient import postgresPreflight
</span><span class="cx"> from txdav.base.datastore.subpostgres import PostgresService
</span><del>-
-from calendarserver.accesslog import DirectoryLogWrapperResource
-from calendarserver.provision.root import RootResource
-from calendarserver.tools.util import checkDirectory
-from calendarserver.webadmin.landing import WebAdminLandingResource
-from calendarserver.webcal.resource import WebCalendarResource
-
</del><ins>+from txdav.caldav.datastore.scheduling.ischedule.dkim import DKIMUtils, DomainKeyResource
+from txdav.caldav.datastore.scheduling.ischedule.localservers import buildServersDB
+from txdav.caldav.datastore.scheduling.ischedule.resource import IScheduleInboxResource
+from txdav.common.datastore.file import CommonDataStore as CommonFileDataStore
</ins><span class="cx"> from txdav.common.datastore.podding.resource import ConduitResource
</span><span class="cx"> from txdav.common.datastore.sql import CommonDataStore as CommonSQLDataStore
</span><del>-from txdav.common.datastore.file import CommonDataStore as CommonFileDataStore
</del><span class="cx"> from txdav.common.datastore.sql import current_sql_schema
</span><span class="cx"> from txdav.common.datastore.upgrade.sql.upgrade import NotAllowedToUpgrade
</span><del>-from twext.python.filepath import CachingFilePath
-from urllib import quote
-from twisted.python.usage import UsageError
</del><ins>+from txdav.dps.client import DirectoryService as DirectoryProxyClientService
+from txdav.who.cache import CachingDirectoryService
+from txdav.who.util import directoryFromConfig
</ins><span class="cx"> 
</span><del>-from twext.who.checker import UsernamePasswordCredentialChecker
-from twext.who.checker import HTTPDigestCredentialChecker
-from twisted.cred.error import UnauthorizedLogin
</del><ins>+from txweb2.auth.basic import BasicCredentialFactory
+from txweb2.dav import auth
</ins><span class="cx"> from txweb2.dav.auth import IPrincipalCredentials
</span><ins>+from txweb2.dav.util import joinURL
+from txweb2.http_headers import Headers
+from txweb2.resource import Resource
+from txweb2.static import File as FileResource
</ins><span class="cx"> 
</span><del>-from twistedcaldav.config import ConfigurationError
-from twistedcaldav.stdconfig import config
</del><ins>+from urllib import quote
+import OpenSSL
+import errno
+import os
+import psutil
+import sys
</ins><span class="cx"> 
</span><ins>+try:
+    from twistedcaldav.authkerb import NegotiateCredentialFactory
+    NegotiateCredentialFactory  # pacify pyflakes
+except ImportError:
+    NegotiateCredentialFactory = None
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> log = Logger()
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -229,6 +230,47 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+def storeFromConfigWithoutDPS(config, txnFactory):
+    store = storeFromConfig(config, txnFactory, None)
+    directory = directoryFromConfig(config, store)
+    if config.DirectoryProxy.InProcessCachingSeconds:
+        directory = CachingDirectoryService(
+            directory,
+            expireSeconds=config.DirectoryProxy.InProcessCachingSeconds
+        )
+    store.setDirectoryService(directory)
+    return store
+
+
+
+def storeFromConfigWithDPSClient(config, txnFactory):
+    store = storeFromConfig(config, txnFactory, None)
+    directory = DirectoryProxyClientService(config.DirectoryRealmName)
+    if config.Servers.Enabled:
+        directory.setServersDB(buildServersDB(config.Servers.MaxClients))
+    if config.DirectoryProxy.InProcessCachingSeconds:
+        directory = CachingDirectoryService(
+            directory,
+            expireSeconds=config.DirectoryProxy.InProcessCachingSeconds
+        )
+    store.setDirectoryService(directory)
+    return store
+
+
+
+def storeFromConfigWithDPSServer(config, txnFactory):
+    store = storeFromConfig(config, txnFactory, None)
+    directory = directoryFromConfig(config, store)
+    if config.DirectoryProxy.InSidecarCachingSeconds:
+        directory = CachingDirectoryService(
+            directory,
+            expireSeconds=config.DirectoryProxy.InSidecarCachingSeconds
+        )
+    store.setDirectoryService(directory)
+    return store
+
+
+
</ins><span class="cx"> def storeFromConfig(config, txnFactory, directoryService):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Produce an L{IDataStore} from the given configuration, transaction factory,
</span></span></pre></div>
<a id="CalendarServertrunkconfcaldavdtestpodAplist"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/conf/caldavd-test-podA.plist (14085 => 14086)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/conf/caldavd-test-podA.plist        2014-10-17 17:22:48 UTC (rev 14085)
+++ CalendarServer/trunk/conf/caldavd-test-podA.plist        2014-10-17 18:24:45 UTC (rev 14086)
</span><span class="lines">@@ -110,48 +110,6 @@
</span><span class="cx">             &lt;string&gt;podding&lt;/string&gt;
</span><span class="cx">         &lt;/dict&gt;
</span><span class="cx"> 
</span><del>-    &lt;key&gt;Scheduling&lt;/key&gt;
-    &lt;dict&gt;
-      &lt;!-- iSchedule protocol options --&gt;
-      &lt;key&gt;iSchedule&lt;/key&gt;
-      &lt;dict&gt;
-        &lt;key&gt;Enabled&lt;/key&gt;
-        &lt;true/&gt;
-        &lt;key&gt;AddressPatterns&lt;/key&gt;
-        &lt;array&gt;
-        &lt;/array&gt;
-        &lt;key&gt;RemoteServers&lt;/key&gt;
-        &lt;string&gt;remoteservers-test.xml&lt;/string&gt;
-        &lt;key&gt;DNSDebug&lt;/key&gt;
-        &lt;string&gt;test-db.zones&lt;/string&gt;
-        &lt;key&gt;DKIM&lt;/key&gt;
-        &lt;dict&gt;
-                &lt;key&gt;Enabled&lt;/key&gt;
-                &lt;true/&gt;
-                &lt;key&gt;Domain&lt;/key&gt;
-                &lt;string&gt;example.com&lt;/string&gt;
-                &lt;key&gt;KeySelector&lt;/key&gt;
-                &lt;string&gt;ischedule&lt;/string&gt;
-                &lt;key&gt;UseDNSKey&lt;/key&gt;
-                &lt;false/&gt;
-                &lt;key&gt;UseHTTPKey&lt;/key&gt;
-                &lt;true/&gt;
-                &lt;key&gt;UsePrivateExchangeKey&lt;/key&gt;
-                &lt;true/&gt;
-                &lt;key&gt;ExpireSeconds&lt;/key&gt;
-                &lt;integer&gt;3600&lt;/integer&gt;
-                &lt;key&gt;PrivateKeyFile&lt;/key&gt;
-                &lt;string&gt;dkim-test/priv.pem&lt;/string&gt;
-                &lt;key&gt;PublicKeyFile&lt;/key&gt;
-                &lt;string&gt;dkim-test/pub.pem&lt;/string&gt;
-                &lt;key&gt;PrivateExchanges&lt;/key&gt;
-                &lt;string&gt;dkim-test/other_keys&lt;/string&gt;
-                &lt;key&gt;ProtocolDebug&lt;/key&gt;
-                &lt;true/&gt;
-        &lt;/dict&gt;
-      &lt;/dict&gt;
-    &lt;/dict&gt;
-
</del><span class="cx">     &lt;key&gt;Notifications&lt;/key&gt;
</span><span class="cx">     &lt;dict&gt;
</span><span class="cx">       &lt;key&gt;Services&lt;/key&gt;
</span></span></pre></div>
<a id="CalendarServertrunkconfcaldavdtestpodBplist"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/conf/caldavd-test-podB.plist (14085 => 14086)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/conf/caldavd-test-podB.plist        2014-10-17 17:22:48 UTC (rev 14085)
+++ CalendarServer/trunk/conf/caldavd-test-podB.plist        2014-10-17 18:24:45 UTC (rev 14086)
</span><span class="lines">@@ -117,48 +117,6 @@
</span><span class="cx">             &lt;string&gt;podding&lt;/string&gt;
</span><span class="cx">         &lt;/dict&gt;
</span><span class="cx"> 
</span><del>-    &lt;key&gt;Scheduling&lt;/key&gt;
-    &lt;dict&gt;
-      &lt;!-- iSchedule protocol options --&gt;
-      &lt;key&gt;iSchedule&lt;/key&gt;
-      &lt;dict&gt;
-        &lt;key&gt;Enabled&lt;/key&gt;
-        &lt;true/&gt;
-        &lt;key&gt;AddressPatterns&lt;/key&gt;
-        &lt;array&gt;
-        &lt;/array&gt;
-        &lt;key&gt;RemoteServers&lt;/key&gt;
-        &lt;string&gt;remoteservers-test.xml&lt;/string&gt;
-        &lt;key&gt;DNSDebug&lt;/key&gt;
-        &lt;string&gt;test-db.zones&lt;/string&gt;
-        &lt;key&gt;DKIM&lt;/key&gt;
-        &lt;dict&gt;
-                &lt;key&gt;Enabled&lt;/key&gt;
-                &lt;true/&gt;
-                &lt;key&gt;Domain&lt;/key&gt;
-                &lt;string&gt;example.com&lt;/string&gt;
-                &lt;key&gt;KeySelector&lt;/key&gt;
-                &lt;string&gt;ischedule&lt;/string&gt;
-                &lt;key&gt;UseDNSKey&lt;/key&gt;
-                &lt;false/&gt;
-                &lt;key&gt;UseHTTPKey&lt;/key&gt;
-                &lt;true/&gt;
-                &lt;key&gt;UsePrivateExchangeKey&lt;/key&gt;
-                &lt;true/&gt;
-                &lt;key&gt;ExpireSeconds&lt;/key&gt;
-                &lt;integer&gt;3600&lt;/integer&gt;
-                &lt;key&gt;PrivateKeyFile&lt;/key&gt;
-                &lt;string&gt;dkim-test/priv.pem&lt;/string&gt;
-                &lt;key&gt;PublicKeyFile&lt;/key&gt;
-                &lt;string&gt;dkim-test/pub.pem&lt;/string&gt;
-                &lt;key&gt;PrivateExchanges&lt;/key&gt;
-                &lt;string&gt;dkim-test/other_keys&lt;/string&gt;
-                &lt;key&gt;ProtocolDebug&lt;/key&gt;
-                &lt;true/&gt;
-        &lt;/dict&gt;
-      &lt;/dict&gt;
-    &lt;/dict&gt;
-
</del><span class="cx">     &lt;key&gt;Notifications&lt;/key&gt;
</span><span class="cx">     &lt;dict&gt;
</span><span class="cx">       &lt;key&gt;Services&lt;/key&gt;
</span><span class="lines">@@ -194,7 +152,7 @@
</span><span class="cx">                     &lt;key&gt;ClientEnabled&lt;/key&gt;
</span><span class="cx">                     &lt;true/&gt;
</span><span class="cx">                     &lt;key&gt;ServerEnabled&lt;/key&gt;
</span><del>-                    &lt;true/&gt;
</del><ins>+                    &lt;false/&gt;
</ins><span class="cx">                     &lt;key&gt;BindAddress&lt;/key&gt;
</span><span class="cx">                     &lt;string&gt;localhost&lt;/string&gt;
</span><span class="cx">                     &lt;key&gt;Port&lt;/key&gt;
</span></span></pre></div>
<a id="CalendarServertrunktxdavdpsserverpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/dps/server.py (14085 => 14086)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/dps/server.py        2014-10-17 17:22:48 UTC (rev 14085)
+++ CalendarServer/trunk/txdav/dps/server.py        2014-10-17 18:24:45 UTC (rev 14086)
</span><span class="lines">@@ -18,7 +18,7 @@
</span><span class="cx"> import datetime
</span><span class="cx"> import uuid
</span><span class="cx"> 
</span><del>-from calendarserver.tap.util import getDBPool, storeFromConfig
</del><ins>+from calendarserver.tap.util import getDBPool, storeFromConfigWithDPSServer
</ins><span class="cx"> from twext.python.log import Logger
</span><span class="cx"> from twext.who.expression import MatchType, MatchFlags, Operand
</span><span class="cx"> from twisted.application import service
</span><span class="lines">@@ -42,8 +42,6 @@
</span><span class="cx">     AddMembersCommand, RemoveMembersCommand,
</span><span class="cx">     UpdateRecordsCommand, # RemoveRecordsCommand,
</span><span class="cx"> )
</span><del>-from txdav.who.cache import CachingDirectoryService
-from txdav.who.util import directoryFromConfig
</del><span class="cx"> from txdav.who.wiki import WikiAccessLevel
</span><span class="cx"> from zope.interface import implementer
</span><span class="cx"> 
</span><span class="lines">@@ -773,14 +771,7 @@
</span><span class="cx"> 
</span><span class="cx">         try:
</span><span class="cx">             _ignore_pool, txnFactory = getDBPool(config)
</span><del>-            store = storeFromConfig(config, txnFactory, None)
-            directory = directoryFromConfig(config)
-            if config.DirectoryProxy.InSidecarCachingSeconds:
-                directory = CachingDirectoryService(
-                    directory,
-                    expireSeconds=config.DirectoryProxy.InSidecarCachingSeconds
-                )
-            store.setDirectoryService(directory)
</del><ins>+            store = storeFromConfigWithDPSServer(config, txnFactory)
</ins><span class="cx">         except Exception as e:
</span><span class="cx">             log.error(&quot;Failed to create directory service&quot;, error=e)
</span><span class="cx">             raise
</span><span class="lines">@@ -792,5 +783,5 @@
</span><span class="cx">             &quot;unix:{path}:mode=660&quot;.format(
</span><span class="cx">                 path=config.DirectoryProxy.SocketPath
</span><span class="cx">             ),
</span><del>-            DirectoryProxyAMPFactory(directory)
</del><ins>+            DirectoryProxyAMPFactory(store.directoryService())
</ins><span class="cx">         )
</span></span></pre></div>
<a id="CalendarServertrunktxdavwhodelegatespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/who/delegates.py (14085 => 14086)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/who/delegates.py        2014-10-17 17:22:48 UTC (rev 14085)
+++ CalendarServer/trunk/txdav/who/delegates.py        2014-10-17 18:24:45 UTC (rev 14086)
</span><span class="lines">@@ -372,6 +372,7 @@
</span><span class="cx">     @rtype: a Deferred which fires a set of L{str}
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><ins>+    log.debug(&quot;_delegatesOfUIDs for: {} and read-write = {} and expanded = {}&quot;.format(delegator.uid, readWrite, expanded,))
</ins><span class="cx">     if delegator.thisServer():
</span><span class="cx">         delegateUIDs = yield txn.delegates(delegator.uid, readWrite, expanded=expanded)
</span><span class="cx">     else:
</span><span class="lines">@@ -401,6 +402,7 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+    log.debug(&quot;_delegatedToUIDs for: {} and read-write = {}&quot;.format(delegate.uid, readWrite,))
</ins><span class="cx">     delegatorUIDs = (yield txn.delegators(delegate.uid, readWrite))
</span><span class="cx">     if not onlyThisServer and config.Servers.Enabled:
</span><span class="cx">         delegatorUIDs.update((yield _podDelegators(txn, delegate, readWrite)))
</span><span class="lines">@@ -438,6 +440,7 @@
</span><span class="cx">     @rtype: a Deferred which fires a set of L{str}
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><ins>+    log.debug(&quot;_podDelegates for: {} and read-write = {} and expanded = {}&quot;.format(delegator.uid, readWrite, expanded,))
</ins><span class="cx">     return txn.store().conduit.send_get_delegates(txn, delegator, readWrite, expanded)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -456,6 +459,7 @@
</span><span class="cx">     @rtype: a Deferred which fires a set of L{str}
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><ins>+    log.debug(&quot;_podDelegators for: {} and read-write = {}&quot;.format(delegate.uid, readWrite,))
</ins><span class="cx">     results = yield DeferredList([
</span><span class="cx">         txn.store().conduit.send_get_delegators(txn, server, delegate, readWrite) for
</span><span class="cx">         server in txn.directoryService().serversDB.allServersExceptThis()
</span></span></pre></div>
<a id="CalendarServertrunktxdavwhotesttest_utilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/who/test/test_util.py (14085 => 14086)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/who/test/test_util.py        2014-10-17 17:22:48 UTC (rev 14085)
+++ CalendarServer/trunk/txdav/who/test/test_util.py        2014-10-17 18:24:45 UTC (rev 14086)
</span><span class="lines">@@ -20,22 +20,23 @@
</span><span class="cx"> 
</span><span class="cx"> import os
</span><span class="cx"> 
</span><del>-from txdav.who.util import directoryFromConfig
-from txdav.who.test.support import InMemoryDirectoryService
</del><ins>+from twext.who.aggregate import DirectoryService as AggregateDirectoryService
+from twext.who.directory import DirectoryRecord
+from twext.who.idirectory import RecordType, NoSuchRecordError
+from twext.who.xml import DirectoryService as XMLDirectoryService
</ins><span class="cx"> from twisted.internet.defer import inlineCallbacks
</span><ins>+from twisted.python.filepath import FilePath
</ins><span class="cx"> from twisted.trial.unittest import TestCase
</span><span class="cx"> from twistedcaldav.config import ConfigDict
</span><del>-from twisted.python.filepath import FilePath
</del><ins>+import twistedcaldav.stdconfig #@UnusedImport
</ins><span class="cx"> from txdav.who.augment import AugmentedDirectoryService
</span><del>-from twext.who.aggregate import DirectoryService as AggregateDirectoryService
-from twext.who.xml import DirectoryService as XMLDirectoryService
</del><span class="cx"> from txdav.who.delegates import (
</span><span class="cx">     DirectoryService as DelegateDirectoryService,
</span><span class="cx">     RecordType as DelegateRecordType
</span><span class="cx"> )
</span><del>-from twext.who.directory import DirectoryRecord
-from twext.who.idirectory import RecordType, NoSuchRecordError
</del><span class="cx"> from txdav.who.idirectory import RecordType as CalRecordType
</span><ins>+from txdav.who.test.support import InMemoryDirectoryService
+from txdav.who.util import directoryFromConfig
</ins><span class="cx"> from txdav.who.wiki import (
</span><span class="cx">     DirectoryService as WikiDirectoryService,
</span><span class="cx">     RecordType as WikiRecordType,
</span><span class="lines">@@ -103,11 +104,14 @@
</span><span class="cx">                         &quot;xmlFiles&quot;: [&quot;augments.xml&quot;],
</span><span class="cx">                     },
</span><span class="cx">                 },
</span><ins>+                &quot;Servers&quot;: {
+                    &quot;Enabled&quot;: False,
+                },
</ins><span class="cx">             }
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx">         store = StubStore()
</span><del>-        service = directoryFromConfig(config, store=store)
</del><ins>+        service = directoryFromConfig(config, store)
</ins><span class="cx"> 
</span><span class="cx">         # Make sure XML files were created
</span><span class="cx">         dataRoot = FilePath(self.dataRoot)
</span></span></pre></div>
<a id="CalendarServertrunktxdavwhoutilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/who/util.py (14085 => 14086)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/who/util.py        2014-10-17 17:22:48 UTC (rev 14085)
+++ CalendarServer/trunk/txdav/who/util.py        2014-10-17 18:24:45 UTC (rev 14086)
</span><span class="lines">@@ -15,7 +15,6 @@
</span><span class="cx"> ##
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-from calendarserver.tap.util import getDBPool, storeFromConfig
</del><span class="cx"> from twext.python.log import Logger
</span><span class="cx"> from twext.python.types import MappingProxyType
</span><span class="cx"> from twext.who.aggregate import DirectoryService as AggregateDirectoryService
</span><span class="lines">@@ -40,12 +39,13 @@
</span><span class="cx"> )
</span><span class="cx"> from txdav.who.wiki import DirectoryService as WikiDirectoryService
</span><span class="cx"> from txdav.who.xml import DirectoryService as XMLDirectoryService
</span><ins>+from txdav.caldav.datastore.scheduling.ischedule.localservers import buildServersDB
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> log = Logger()
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-def directoryFromConfig(config, store=None, serversDB=None):
</del><ins>+def directoryFromConfig(config, store):
</ins><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Return a directory service based on the config.  If you want to go through
</span><span class="cx">     AMP to talk to one of these as a client, instantiate
</span><span class="lines">@@ -62,10 +62,10 @@
</span><span class="cx"> 
</span><span class="cx">     # TODO: use proxyForInterface to ensure we're only using the DPS related
</span><span class="cx">     # store API.  Also define an IDirectoryProxyStore Interface
</span><del>-    if store is None:
-        _ignore_pool, txnFactory = getDBPool(config)
-        store = storeFromConfig(config, txnFactory, None)
</del><ins>+    assert store is not None
</ins><span class="cx"> 
</span><ins>+    serversDB = buildServersDB(config.Servers.MaxClients) if config.Servers.Enabled else None
+
</ins><span class="cx">     return buildDirectory(
</span><span class="cx">         store,
</span><span class="cx">         config.DataRoot,
</span></span></pre>
</div>
</div>

</body>
</html>