Permalink
Browse files

Merge remote-tracking branch 'origin/release-4.6-update-2'

  • Loading branch information...
2 parents 83365d8 + be9053d commit f8cffd18da3797885e54251874cb833e1b397a95 @ezuce-admin ezuce-admin committed Jan 31, 2013
Showing with 2,782 additions and 874 deletions.
  1. +6 −0 mak/rpm.mk.in
  2. +22 −0 sipXcommons/src/main/java/org/sipfoundry/commons/userdb/ValidUsers.java
  3. +23 −1 sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cfgmgt/ConfigManagerImpl.java
  4. +29 −0 sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/common/MongoGenerationFinishedEvent.java
  5. +35 −27 sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/commserver/imdb/ReplicationManagerImpl.java
  6. +0 −1 sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/commserver/imdb/imdb.beans.xml
  7. +2 −3 sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/rls/ResourceLists.java
  8. +11 −5 sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/speeddial/SpeedDialManagerImpl.java
  9. +1 −1 sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/speeddial/speeddial.beans.xml
  10. +11 −0 sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/speeddial/SpeedDialManagerTestIntegration.java
  11. +2 −1 sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/OpenAcdLinesResource.java
  12. +1 −0 sipXportLib/include/Makefile.am
  13. +202 −0 sipXportLib/include/os/OsTimerQueue.h
  14. +1 −0 sipXportLib/src/Makefile.am
  15. +92 −0 sipXportLib/src/os/OsTimerQueue.cpp
  16. +1 −0 sipXportLib/src/test/Makefile.am
  17. +433 −0 sipXportLib/src/test/os/OsTimerQueueTest.cpp
  18. +5 −0 sipXproxy/lib/authplugins/NatTraversalAgent/DialogTracker.cpp
  19. +5 −0 sipXproxy/src/ForwardRules.cpp
  20. +75 −39 sipXrls/src/ContactSet.cpp
  21. +3 −0 sipXrls/src/ContactSet.h
  22. +2 −0 sipXrls/src/ResourceInstance.cpp
  23. +31 −1 sipXrls/src/ResourceList.cpp
  24. +8 −6 sipXrls/src/ResourceList.h
  25. +71 −0 sipXrls/src/ResourceListMsg.cpp
  26. +54 −1 sipXrls/src/ResourceListMsg.h
  27. +132 −122 sipXrls/src/ResourceListSet.cpp
  28. +30 −7 sipXrls/src/ResourceListSet.h
  29. +13 −0 sipXrls/src/ResourceListTask.cpp
  30. +2 −0 sipXrls/src/ResourceNotifyReceiver.cpp
  31. +67 −0 sipXrls/src/ResourceNotifyReceiver.h
  32. +2 −0 sipXrls/src/ResourceSubscriptionReceiver.cpp
  33. +66 −1 sipXrls/src/ResourceSubscriptionReceiver.h
  34. +5 −0 sipXrls/src/SubscriptionSet.cpp
  35. +17 −4 sipXsaa/src/AppAgentTask.cpp
  36. +71 −46 sipXsaa/src/AppearanceGroup.cpp
  37. +3 −0 sipXsaa/src/AppearanceGroup.h
  38. +28 −1 sipXsaa/src/AppearanceGroupSet.cpp
  39. +14 −0 sipXsaa/src/AppearanceGroupSet.h
  40. +74 −2 sipXsaa/src/ResourceListMsg.cpp
  41. +56 −2 sipXsaa/src/ResourceListMsg.h
  42. +260 −13 sipXtackLib/include/net/SipSubscribeClient.h
  43. +813 −589 sipXtackLib/src/net/SipSubscribeClient.cpp
  44. +1 −0 sipXtackLib/src/net/SipUserAgent.cpp
  45. +1 −0 sipXtackLib/src/test/net/SipSubscribeClientTest.cpp
  46. +1 −1 sipXtackLib/src/test/net/SipXauthIdentityTest.cpp.in
View
@@ -182,5 +182,11 @@ repo-update :
mock $(MOCK_OPTS) --scrub=yum-cache
mock $(MOCK_OPTS) --update
+help.repo-quick-update = Remove only the packages from chroot that are built. Takes 14 seconds when a full rebuild can take 2 minutues
+repo-quick-update :
+ rpm -qp --queryformat '%{name}\n' $(MOCK_RESULTS_DIR)/*.rpm | sort | uniq | \
+ xargs --no-run-if-empty mock $(MOCK_OPTS) --remove
+ find mock-cache/$(DISTRO)/yum_cache/sipxecs/packages/ -name '*.rpm' | xargs --no-run-if-empty rm
+
help.repo = Prepares repository for $(DISTRO) for publishing or re-distributing in ISO by removing extra rpms and moving source rpms to separate directory.
repo: repo-src repo-remove-dups repo-create;
@@ -40,6 +40,7 @@
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
+import com.mongodb.WriteResult;
import com.mongodb.util.JSON;
/**
@@ -107,6 +108,27 @@ public DBCursor getUsers() {
return cursor;
}
+ public DBCursor getUsersWithSpeedDial() {
+ DBCursor cursor = getEntityCollection().find(
+ QueryBuilder.start(ENTITY_NAME).is(ENTITY_NAME_USER).
+ or(
+ QueryBuilder.start(SPEEDDIAL).exists(true).get(),
+ new BasicDBObject(IM_ENABLED, "true")
+ ).get());
+ return cursor;
+ }
+
+ /**
+ * Use this method if you need to remove a field from users completely.
+ * This may be achieved by regenerating the entire collection, or a DataSet, but this would be much faster.
+ * @param field
+ */
+ public void removeFieldFromUsers(String field) {
+ getEntityCollection().update( new BasicDBObject()
+ , new BasicDBObject( "$unset" , new BasicDBObject( SPEEDDIAL , 1 ) )
+ , false , true );
+ }
+
/**
* Loading all users into memory is an extremely expensive call for large systems (10K-50K user system).
* Consider refactoring your code to not call this method.
@@ -35,6 +35,7 @@
import org.sipfoundry.sipxconfig.alarm.AlarmProvider;
import org.sipfoundry.sipxconfig.alarm.AlarmServerManager;
import org.sipfoundry.sipxconfig.common.LazyDaemon;
+import org.sipfoundry.sipxconfig.common.MongoGenerationFinishedEvent;
import org.sipfoundry.sipxconfig.commserver.Location;
import org.sipfoundry.sipxconfig.commserver.LocationsManager;
import org.sipfoundry.sipxconfig.commserver.SipxReplicationContext;
@@ -48,9 +49,10 @@
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Required;
+import org.springframework.context.ApplicationListener;
public class ConfigManagerImpl implements AddressProvider, ConfigManager, BeanFactoryAware, AlarmProvider,
- ConfigCommands, SetupListener {
+ ConfigCommands, SetupListener, ApplicationListener<MongoGenerationFinishedEvent> {
private static final Log LOG = LogFactory.getLog(ConfigManagerImpl.class);
private File m_cfDataDir;
private DomainManager m_domainManager;
@@ -69,6 +71,8 @@
private String m_uploadDir;
private Set<String> m_registeredIps;
private boolean m_postSetup;
+ private final Object m_lock = new Object();
+ private boolean m_flag;
@Override
public synchronized void configureEverywhere(Feature... features) {
@@ -99,6 +103,7 @@ public synchronized void configureAllFeatures(Collection<Location> locations) {
@Override
public synchronized void regenerateMongo(Collection<Location> locations) {
if (locations.contains(m_locationManager.getPrimaryLocation())) {
+ m_flag = true;
m_sipxReplicationContext.generateAll();
}
}
@@ -149,6 +154,15 @@ public void runProviders() {
}
private void runProviders(ConfigRequest request, String jobLabel) {
+ synchronized (m_lock) {
+ try {
+ while (m_flag) {
+ m_lock.wait();
+ }
+ } catch (InterruptedException e) {
+ LOG.warn("Thread interrupted. Config might be in stale state; rerun send profiles.");
+ }
+ }
LOG.info("Configuration work to do. Notifying providers.");
Serializable job = m_jobContext.schedule(jobLabel);
m_jobContext.start(job);
@@ -391,4 +405,12 @@ public boolean setup(SetupManager manager) {
notifyWorker();
return true;
}
+
+ @Override
+ public void onApplicationEvent(MongoGenerationFinishedEvent event) {
+ synchronized (m_lock) {
+ m_flag = false;
+ m_lock.notifyAll();
+ }
+ }
}
@@ -0,0 +1,29 @@
+/**
+ *
+ *
+ * Copyright (c) 2013 eZuce, Inc. All rights reserved.
+ * Contributed to SIPfoundry under a Contributor Agreement
+ *
+ * This software is free software; you can redistribute it and/or modify it under
+ * the terms of the Affero General Public License (AGPL) as published by the
+ * Free Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+ * details.
+ */
+package org.sipfoundry.sipxconfig.common;
+
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * Signifying sipXconfig application has finished file replications
+ */
+public class MongoGenerationFinishedEvent extends ApplicationEvent {
+
+ public MongoGenerationFinishedEvent(Object src) {
+ super(src);
+ }
+}
@@ -39,6 +39,7 @@
import org.sipfoundry.sipxconfig.common.Closure;
import org.sipfoundry.sipxconfig.common.CoreContext;
import org.sipfoundry.sipxconfig.common.DaoUtils;
+import org.sipfoundry.sipxconfig.common.MongoGenerationFinishedEvent;
import org.sipfoundry.sipxconfig.common.Replicable;
import org.sipfoundry.sipxconfig.common.ReplicableProvider;
import org.sipfoundry.sipxconfig.common.SipxHibernateDaoSupport;
@@ -48,7 +49,6 @@
import org.sipfoundry.sipxconfig.common.VersionInfo;
import org.sipfoundry.sipxconfig.commserver.Location;
import org.sipfoundry.sipxconfig.commserver.LocationsManager;
-import org.sipfoundry.sipxconfig.forwarding.ForwardingContext;
import org.sipfoundry.sipxconfig.logging.AuditLogContext;
import org.sipfoundry.sipxconfig.permission.Permission;
import org.sipfoundry.sipxconfig.setting.Group;
@@ -58,6 +58,8 @@
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Required;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
import org.springframework.data.mongodb.core.MongoTemplate;
import com.mongodb.BasicDBObject;
@@ -73,7 +75,7 @@
* {@link ConfigurationFile}s on different locations.
*/
public class ReplicationManagerImpl extends SipxHibernateDaoSupport implements ReplicationManager, BeanFactoryAware,
- SetupListener {
+ SetupListener, ApplicationContextAware {
private static final Log LOG = LogFactory.getLog(ReplicationManagerImpl.class);
private static final String REPLICATION_FAILED = "Replication: insert/update failed - ";
private static final String REPLICATION_FAILED_REMOVE = "Replication: delete failed - ";
@@ -96,12 +98,12 @@
private AuditLogContext m_auditLogContext;
private ListableBeanFactory m_beanFactory;
private CoreContext m_coreContext;
- private ForwardingContext m_forwardingContext;
private ExternalAliases m_externalAliases;
private int m_pageSize = 1000;
private int m_nThreads = 2;
private boolean m_useDynamicPageSize;
private DataSet m_dataSet;
+ private ApplicationContext m_applicationContext;
private final Closure<User> m_userClosure = new Closure<User>() {
@Override
@@ -165,7 +167,7 @@ public void dropDatasetDb() {
}
/*
- * Callable used in the async replication of a large group of entities, namely all users. We
+ * Callable used in the parallel replication of a large group of entities, namely all users. We
* use Callable and not Runnable, b/c we need to wait for the termination of the threads
* calling it.
*/
@@ -278,22 +280,27 @@ public Void call() {
*/
@Override
public void replicateAllData() {
- Location primary = m_locationsManager.getPrimaryLocation();
- dropDatasetDb();
- int membersCount = m_coreContext.getAllUsersCount();
- doParallelAsyncReplication(membersCount, ReplicationWorker.class, null);
- // get the rest of Replicables and replicate them
- Map<String, ReplicableProvider> beanMap = m_beanFactory.getBeansOfType(ReplicableProvider.class);
- for (ReplicableProvider provider : beanMap.values()) {
- for (Replicable entity : provider.getReplicables()) {
- replicateEntity(entity);
+ try {
+ Location primary = m_locationsManager.getPrimaryLocation();
+ dropDatasetDb();
+ int membersCount = m_coreContext.getAllUsersCount();
+ doParallelReplication(membersCount, ReplicationWorker.class, null);
+ // get the rest of Replicables and replicate them
+ Map<String, ReplicableProvider> beanMap = m_beanFactory.getBeansOfType(ReplicableProvider.class);
+ for (ReplicableProvider provider : beanMap.values()) {
+ for (Replicable entity : provider.getReplicables()) {
+ replicateEntity(entity);
+ }
}
+ // Replicate the external aliases
+ ExternalAlias extalias = new ExternalAlias();
+ extalias.setFiles(m_externalAliases.getFiles());
+ replicateEntity(extalias);
+ m_auditLogContext.logReplicationMongo(DATABASE_REGENERATION, primary);
+ } finally {
+ m_applicationContext.publishEvent(new MongoGenerationFinishedEvent(this));
}
- // Replicate the external aliases
- ExternalAlias extalias = new ExternalAlias();
- extalias.setFiles(m_externalAliases.getFiles());
- replicateEntity(extalias);
- m_auditLogContext.logReplicationMongo(DATABASE_REGENERATION, primary);
+
}
/**
@@ -387,7 +394,7 @@ public void replicateAllData(final DataSet ds) {
}
int membersCount = m_coreContext.getAllUsersCount();
m_dataSet = ds;
- doParallelAsyncReplication(membersCount, ReplicationWorkerDataSet.class, null);
+ doParallelReplication(membersCount, ReplicationWorkerDataSet.class, null);
Long end = System.currentTimeMillis();
LOG.info(REGENERATION_OF + ds.getName() + " completed in " + (end - start) / 1000 + SECONDS
+ (end - start) / 1000 / 60 + MINUTES);
@@ -412,7 +419,7 @@ public void replicateSpeedDialGroup(Group group) {
private void replicateGroupWithWorker(Group group, Class<? extends ReplicationWorker> worker) {
try {
int membersCount = m_coreContext.getGroupMembersCount(group.getId());
- doParallelAsyncReplication(membersCount, worker, group);
+ doParallelReplication(membersCount, worker, group);
LOG.info("Regeneration of group complete");
} catch (Exception e) {
LOG.error("Regeneration of group failed", e);
@@ -426,7 +433,7 @@ public void replicateBranch(Branch branch) {
Location primary = m_locationsManager.getPrimaryLocation();
try {
int membersCount = m_coreContext.getBranchMembersCount(branch.getId());
- doParallelAsyncReplication(membersCount, AllBranchMembersReplicationWorker.class, branch);
+ doParallelReplication(membersCount, AllBranchMembersReplicationWorker.class, branch);
m_auditLogContext.logReplicationMongo(BRANCH_REGENERATION, primary);
} catch (Exception e) {
m_auditLogContext.logReplicationMongoFailed(BRANCH_REGENERATION, primary, e);
@@ -476,7 +483,7 @@ public void deleteGroup(Group group) {
* synchronise here. We do not want multiple threads doing heavy replication stuff at the same time.
* (i.e. if we hit send profiles, then do a change on group with 20.000 members)
*/
- private synchronized void doParallelAsyncReplication(int membersCount,
+ private synchronized void doParallelReplication(int membersCount,
Class<? extends ReplicationWorker> cls, Object type) {
ExecutorService replicationExecutorService = Executors.newFixedThreadPool(m_nThreads);
Long start = System.currentTimeMillis();
@@ -489,7 +496,7 @@ private synchronized void doParallelAsyncReplication(int membersCount,
Constructor<? extends ReplicationWorker> ct = (Constructor< ? extends ReplicationWorker>)
cls.getConstructors()[0];
List<Future<Void>> futures = new ArrayList<Future<Void>>();
- LOG.info("Starting async parallel regeneration of mongo group of "
+ LOG.info("Starting parallel regeneration of mongo group of "
+ membersCount + " entities on " + m_nThreads
+ " threads using chunks of " + pageSize
+ " users");
@@ -707,10 +714,6 @@ public void setCoreContext(CoreContext coreContext) {
m_coreContext = coreContext;
}
- public void setForwardingContext(ForwardingContext forwardingContext) {
- m_forwardingContext = forwardingContext;
- }
-
public void setExternalAliases(ExternalAliases externalAliases) {
m_externalAliases = externalAliases;
}
@@ -744,6 +747,11 @@ public void setImdb(MongoTemplate imdb) {
}
@Override
+ public void setApplicationContext(ApplicationContext applicationContext) {
+ m_applicationContext = applicationContext;
+ }
+
+ @Override
public boolean setup(SetupManager manager) {
String id = "replication-" + new VersionInfo().getVersion();
if (manager.isFalse(id)) {
@@ -77,7 +77,6 @@
<property name="locationsManager" ref="locationsManager" />
<property name="auditLogContext" ref="auditLogContext" />
<property name="coreContext" ref="coreContext" />
- <property name="forwardingContext" ref="forwardingContext" />
<property name="externalAliases" ref="externalAliases" />
<property name="validUsers" ref="validUsers"/>
<property name="imdb" ref="imdb"/>
@@ -44,9 +44,8 @@ public Document getDocument(boolean xmppPresenceEnabled) {
Document document = XmlFile.FACTORY.createDocument();
Element lists = document.addElement("lists", NAMESPACE);
Element imList = null;
- // TIP : To avoid loading all users, can't this query
- // use { "spdl" : { "$exists" : true } } instead? --Douglas
- DBCursor cursor = m_validUsers.getUsers();
+
+ DBCursor cursor = m_validUsers.getUsersWithSpeedDial();
while (cursor.hasNext()) {
DBObject user = cursor.next();
String userName = user.get(UID).toString();
@@ -9,12 +9,15 @@
*/
package org.sipfoundry.sipxconfig.speeddial;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
+import org.sipfoundry.commons.mongo.MongoConstants;
+import org.sipfoundry.commons.userdb.ValidUsers;
import org.sipfoundry.sipxconfig.cfgmgt.ConfigManager;
import org.sipfoundry.sipxconfig.common.CoreContext;
import org.sipfoundry.sipxconfig.common.SipxHibernateDaoSupport;
@@ -33,7 +36,7 @@
private CoreContext m_coreContext;
private FeatureManager m_featureManager;
private ConfigManager m_configManager;
- private SipxReplicationContext m_sipxReplicationContext;
+ private ValidUsers m_validUsers;
@Override
public SpeedDial getSpeedDialForUserId(Integer userId, boolean create) {
@@ -188,7 +191,7 @@ public void clear() {
// A little convoluted, but only way i could keep mongo and postgres in sync
// which is critical for resource-lists.xml.
- m_sipxReplicationContext.generateAll(DataSet.SPEED_DIAL);
+ m_validUsers.removeFieldFromUsers(MongoConstants.SPEEDDIAL);
m_configManager.configureEverywhere(Rls.FEATURE);
}
@@ -197,8 +200,11 @@ public void setConfigManager(ConfigManager configManager) {
m_configManager = configManager;
}
- @Required
- public void setSipxReplicationContext(SipxReplicationContext sipxReplicationContext) {
- m_sipxReplicationContext = sipxReplicationContext;
+ public ValidUsers getValidUsers() {
+ return m_validUsers;
+ }
+
+ public void setValidUsers(ValidUsers validUsers) {
+ m_validUsers = validUsers;
}
}
@@ -17,7 +17,7 @@
<property name="coreContext" ref="coreContext" />
<property name="featureManager" ref="featureManager" />
<property name="configManager" ref="configManager" />
- <property name="sipxReplicationContext" ref="sipxReplicationContextImpl" />
+ <property name="validUsers" ref="validUsers" />
</bean>
<bean id="speedDialOnEdit" class="org.sipfoundry.sipxconfig.speeddial.SpeadDialOnEdit">
Oops, something went wrong.

0 comments on commit f8cffd1

Please sign in to comment.