Merge "Issue #2613 Registry peformance enhancements -- Added indexes to registry tables -- Better cleanup when a registry leaves the federation -- Batching of queries in notification handler to reduce number of web service calls -- Added Hibernate flushes and clears to better manage memory" into omaha_14.2.1

Former-commit-id: a8de0766f4 [formerly a8de0766f4 [formerly ebfeb3ae2cd6fa1f00bc4f7a0955f11afe2ff8ef]]
Former-commit-id: 190a54707d
Former-commit-id: 396d71b2fc
This commit is contained in:
Nate Jensen 2014-01-15 17:36:52 -06:00 committed by Gerrit Code Review
commit 02bf4299f4
10 changed files with 471 additions and 178 deletions

View file

@ -21,11 +21,7 @@ package com.raytheon.uf.common.registry.services;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.nio.charset.StandardCharsets;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
@ -40,9 +36,6 @@ import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.ConnectionType;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.io.Resources;
import com.raytheon.uf.common.comm.ProxyConfiguration;
import com.raytheon.uf.common.registry.RegistryJaxbManager;
@ -68,6 +61,7 @@ import com.raytheon.uf.common.registry.services.rest.IRepositoryItemsRestService
* 10/30/2013 1538 bphillip Moved data delivery services out of registry plugin
* 11/20/2013 2534 bphillip Added HTTPClient policy for rest connections. Eliminated service caching.
* 12/2/2013 1829 bphillip Removed expectedType argument on getRegistryObject method
* 1/15/2014 2613 bphillip Removed Service cache due to unexpected behavior
* </pre>
*
* @author bphillip
@ -99,8 +93,6 @@ public class RegistryRESTServices {
}
}
private Map<Class<?>, LoadingCache<String, ?>> serviceCache = new HashMap<Class<?>, LoadingCache<String, ?>>();
public RegistryRESTServices() throws JAXBException {
jaxbManager = new RegistryJaxbManager(new RegistryNamespaceMapper());
}
@ -179,8 +171,8 @@ public class RegistryRESTServices {
public Object accessXMLRestService(String url) {
String response = null;
try {
response = Resources
.toString(new URL(url), Charset.forName("UTF8"));
;
response = Resources.toString(new URL(url), StandardCharsets.UTF_8);
} catch (Exception e) {
throw new RegistryServiceException(
"Error accessing REST service at URL: [" + url + "]", e);
@ -194,26 +186,9 @@ public class RegistryRESTServices {
}
}
@SuppressWarnings("unchecked")
protected <T extends Object> T getPort(String serviceUrl,
final Class<T> serviceInterface) {
LoadingCache<String, ?> cache = serviceCache.get(serviceInterface);
if (cache == null) {
cache = CacheBuilder.newBuilder()
.expireAfterAccess(1, TimeUnit.MINUTES)
.build(new CacheLoader<String, T>() {
public T load(String key) {
return createService(key, serviceInterface);
}
});
serviceCache.put(serviceInterface, cache);
}
try {
return (T) cache.get(serviceUrl);
} catch (ExecutionException e) {
throw new RuntimeException("Error getting service at ["
+ serviceUrl + "]", e);
}
return createService(serviceUrl, serviceInterface);
}
protected <T extends Object> T createService(String url,

View file

@ -27,8 +27,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
@ -51,9 +49,6 @@ import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.ConnectionType;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.raytheon.uf.common.comm.ProxyConfiguration;
import com.raytheon.uf.common.comm.ProxyUtil;
import com.raytheon.uf.common.localization.PathManagerFactory;
@ -77,6 +72,7 @@ import com.raytheon.uf.common.status.UFStatus;
* 9/5/2013 1538 bphillip Add HTTP header information
* 10/30/2013 1538 bphillip Made methods in this class non-static
* 11/20/2013 2534 bphillip Eliminated service caching
* 1/15/2014 2613 bphillip Eliminated service caching...again
* </pre>
*
* @author bphillip
@ -118,13 +114,18 @@ public class RegistrySOAPServices {
private static final ProxyConfiguration proxyConfig;
protected static final HTTPClientPolicy httpClientPolicy;
protected static final String HTTP_RECEIVE_TIMEOUT_PROPERTY = "ebxml-http-receive-timeout";
protected static final String HTTP_CONNECTION_TIMEOUT_PROPERTY = "ebxml-http-connection-timeout";
static {
proxyConfig = getProxyConfiguration();
httpClientPolicy = new HTTPClientPolicy();
try {
httpClientPolicy.setReceiveTimeout(Long.parseLong(System
.getProperty("ebxml-http-receive-timeout")));
.getProperty(HTTP_RECEIVE_TIMEOUT_PROPERTY)));
} catch (NumberFormatException e) {
statusHandler
.error("ebxml-http-receive-timeout not specified. Using default value of 1 minute",
@ -133,7 +134,7 @@ public class RegistrySOAPServices {
}
try {
httpClientPolicy.setConnectionTimeout(Long.parseLong(System
.getProperty("ebxml-http-connection-timeout")));
.getProperty(HTTP_CONNECTION_TIMEOUT_PROPERTY)));
} catch (NumberFormatException e) {
statusHandler
.error("ebxml-http-connection-timeout not specified. Using default value of 10 seconds",
@ -149,8 +150,6 @@ public class RegistrySOAPServices {
}
}
private Map<Class<?>, LoadingCache<String, ?>> serviceCache = new HashMap<Class<?>, LoadingCache<String, ?>>();
/**
* Gets the notification listener service URL for the given host
*
@ -355,26 +354,9 @@ public class RegistrySOAPServices {
return port;
}
@SuppressWarnings("unchecked")
private <T extends Object> T getPort(String serviceUrl,
final Class<T> serviceInterface) {
LoadingCache<String, ?> cache = serviceCache.get(serviceInterface);
if (cache == null) {
cache = CacheBuilder.newBuilder()
.expireAfterAccess(1, TimeUnit.MINUTES)
.build(new CacheLoader<String, T>() {
public T load(String key) {
return createService(key, serviceInterface);
}
});
serviceCache.put(serviceInterface, cache);
}
try {
return (T) cache.get(serviceUrl);
} catch (ExecutionException e) {
throw new RuntimeException("Error getting service at ["
+ serviceUrl + "]", e);
}
return createService(serviceUrl, serviceInterface);
}
/**

View file

@ -50,6 +50,7 @@ import oasis.names.tc.ebxml.regrep.xsd.rs.v4.RegistryExceptionType;
import oasis.names.tc.ebxml.regrep.xsd.rs.v4.RegistryRequestType;
import oasis.names.tc.ebxml.regrep.xsd.rs.v4.RegistryResponseType;
import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@ -91,6 +92,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
* 2012 bphillip Initial implementation
* 10/17/2013 1682 bphillip Added software history
* 12/2/2013 1829 bphillip Made ExtensibleObjectType persistable, modified persistence annotations, added hashCode and equals
* 1/15/2014 2613 bphillip Added batch size Slot field
* </pre>
*
* @author bphillip
@ -124,6 +126,7 @@ public abstract class ExtensibleObjectType implements Serializable,
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id", nullable = false, referencedColumnName = "id")
@XmlElement(name = "Slot")
@BatchSize(size = 50)
@DynamicSerializeElement
protected List<SlotType> slot;

View file

@ -84,6 +84,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
* 12/2/2013 1829 bphillip Made ExtensibleObjectType persistable,
* modified persistence annotations, added
* constructors, hashCode, toString and equals
* 1/15/2014 2613 bphillip Removed automatically created index
* </pre>
*
* @author bphillip
@ -96,9 +97,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
@Entity
@Cache(region = RegrepUtil.DB_CACHE_REGION, usage = CacheConcurrencyStrategy.TRANSACTIONAL, include = "all")
@Table(schema = RegrepUtil.EBXML_SCHEMA, name = "Slot")
@org.hibernate.annotations.Table(appliesTo = "Slot", indexes = {
@Index(name = "slot_idx", columnNames = { "parent_id" }),
@Index(name = "value_idx", columnNames = { "value_id" }) })
@org.hibernate.annotations.Table(appliesTo = "Slot", indexes = { @Index(name = "value_idx", columnNames = { "value_id" }) })
public class SlotType extends ExtensibleObjectType implements
IPersistableDataObject<String> {

View file

@ -45,6 +45,7 @@ import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.LifecycleManager;
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException;
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.QueryManager;
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.Mode;
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.RemoveObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.SubmitObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryRequest;
import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryResponse;
@ -52,6 +53,7 @@ import oasis.names.tc.ebxml.regrep.xsd.query.v4.ResponseOptionType;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AssociationType;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.DeliveryInfoType;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.FederationType;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ObjectRefListType;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ObjectRefType;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.OrganizationType;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.PersonType;
@ -65,7 +67,9 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.VersionInfoType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
@ -151,6 +155,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
* 11/20/2013 2534 bphillip Consolidated RegistryReplicationManager into this class and added reciprocal subscriptions. Added remote subscription monitor.
* 12/2/2013 1829 bphillip Modified to use correct getters for slot values
* 12/9/2013 2613 bphillip Optimized registry sync function
* 1/15/2014 2613 bphillip Added leaveFederation method to prevent inactive registries from participating in the federation unintentionally.
* </pre>
*
* @author bphillip
@ -203,7 +208,10 @@ public class RegistryFederationManager implements RegistryInitializedListener {
protected String ncfAddress = System.getenv("NCF_ADDRESS");
/** The mode that EDEX was started in */
private String registryMode = System.getProperty("edex.run.mode");
public static final boolean centralRegistry = System.getProperty(
"edex.run.mode").equals(CENTRAL_REGISTRY_MODE);
private static final String FEDERATION_SYNC_THREADS_PROPERTY = "ebxml-federation-sync-threads";
/**
* When a federation sync is necessary, this is the number of threads that
@ -307,9 +315,9 @@ public class RegistryFederationManager implements RegistryInitializedListener {
"Error initializing JAXB Manager!", e);
}
if (System.getProperty("ebxml-federation-sync-threads") != null) {
if (System.getProperty(FEDERATION_SYNC_THREADS_PROPERTY) != null) {
registrySyncThreads = Integer.valueOf(System
.getProperty("ebxml-federation-sync-threads"));
.getProperty(FEDERATION_SYNC_THREADS_PROPERTY));
}
/*
@ -400,7 +408,7 @@ public class RegistryFederationManager implements RegistryInitializedListener {
RegistryServiceException, JAXBException {
FederationType federation = null;
if (isCentralRegistry()) {
if (centralRegistry) {
statusHandler.info("Creating Federation object...");
federation = new FederationType();
federation.setId(FEDERATION_ID);
@ -502,7 +510,7 @@ public class RegistryFederationManager implements RegistryInitializedListener {
"Error submitting federation objects to registry", e);
}
if (!isCentralRegistry()) {
if (!centralRegistry) {
statusHandler
.info("Submitting federation registration objects to NCF...");
try {
@ -1124,14 +1132,24 @@ public class RegistryFederationManager implements RegistryInitializedListener {
statusHandler
.info("Registry shutting down. Removing subscriptions from: ["
+ remoteRegistryBaseURL + "]");
dataDeliveryRestClient
.getRegistryDataAccessService(
remoteRegistryBaseURL)
.removeSubscriptionsForSite(
federationProperties
.getSiteIdentifier());
statusHandler.info("Subscriptions removed from: ["
+ remoteRegistryBaseURL + "]");
if (dataDeliveryRestClient
.isRegistryAvailable(remoteRegistryBaseURL)) {
dataDeliveryRestClient
.getRegistryDataAccessService(
remoteRegistryBaseURL)
.removeSubscriptionsForSite(
federationProperties
.getSiteIdentifier());
statusHandler
.info("Subscriptions removed from: ["
+ remoteRegistryBaseURL + "]");
} else {
statusHandler
.warn("Registry at ["
+ remoteRegistryBaseURL
+ "] is not available. Unable to remove subscriptions.");
}
}
});
return true;
@ -1240,7 +1258,17 @@ public class RegistryFederationManager implements RegistryInitializedListener {
.warn("Registry at ["
+ remoteRegistryUrl
+ "] is unavailable. Unable to verify subscriptions");
return;
continue;
}
if (!Boolean.parseBoolean(dataDeliveryRestClient
.getFederationService(remoteRegistryUrl)
.isFederated())) {
statusHandler
.warn("Registry at ["
+ remoteRegistryUrl
+ "] is currently not participating in the federation. Skipping subscription verification");
continue;
}
int resubmissions = 0;
QueryManager remoteQueryManager = registrySoapServices
@ -1335,39 +1363,36 @@ public class RegistryFederationManager implements RegistryInitializedListener {
scheduler.schedule(this, 10, TimeUnit.SECONDS);
}
}
}
private boolean joinFederation() {
public boolean joinFederation() {
try {
try {
try {
if (!isCentralRegistry()) {
if (dataDeliveryRestClient
.isRegistryAvailable(ncfAddress)) {
statusHandler
.info("NCF Registry is available. Attempting to join federation...");
} else {
statusHandler
.error("Unable to join federation. NCF is currently unreachable.");
return false;
}
}
List<RegistryObjectType> objects = new ArrayList<RegistryObjectType>(
5);
RegistryType registry = federationProperties
.createRegistryObject();
OrganizationType org = federationProperties
.createOrganization();
PersonType primaryContact = federationProperties
.createPrimaryContactPerson();
FederationType federation = getFederation();
AssociationType federationAssociation = null;
if (federation == null) {
if (!centralRegistry) {
if (dataDeliveryRestClient.isRegistryAvailable(ncfAddress)) {
statusHandler
.error("Unable to join federation. Federation Object not found.");
.info("NCF Registry is available. Attempting to join federation...");
} else {
federationAssociation = getFederationAssociation(
registry, federation);
statusHandler
.error("Unable to join federation. NCF is currently unreachable.");
return false;
}
if (isCentralRegistry()) {
}
List<RegistryObjectType> objects = new ArrayList<RegistryObjectType>(
5);
final RegistryType registry = federationProperties
.createRegistryObject();
final OrganizationType org = federationProperties
.createOrganization();
final PersonType primaryContact = federationProperties
.createPrimaryContactPerson();
FederationType federation = getFederation();
if (federation != null) {
final AssociationType federationAssociation = getFederationAssociation(
registry, federation);
if (centralRegistry) {
objects.add(federation);
}
objects.add(registry);
@ -1381,20 +1406,82 @@ public class RegistryFederationManager implements RegistryInitializedListener {
statusHandler
.warn("No replication servers have been specified!");
}
return true;
} catch (EbxmlRegistryException e) {
statusHandler.error("Error registering with federation", e);
return false;
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
txTemplate
.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(
TransactionStatus status) {
leaveFederation();
}
});
}
});
}
} catch (Throwable e) {
statusHandler.error("Error initializing EBXML database!", e);
return true;
} catch (EbxmlRegistryException e) {
statusHandler.error("Error registering with federation", e);
return false;
}
} catch (Throwable e) {
statusHandler.error("Error initializing EBXML database!", e);
return false;
}
}
private boolean isCentralRegistry() {
return registryMode.equals(CENTRAL_REGISTRY_MODE);
public boolean leaveFederation() {
try {
final RegistryType registry = federationProperties
.createRegistryObject();
final OrganizationType org = federationProperties
.createOrganization();
final PersonType primaryContact = federationProperties
.createPrimaryContactPerson();
FederationType federation = getFederation();
if (federation != null) {
final AssociationType federationAssociation = getFederationAssociation(
registry, federation);
ObjectRefListType refList = new ObjectRefListType();
refList.getObjectRef().add(new ObjectRefType(registry.getId()));
refList.getObjectRef().add(new ObjectRefType(org.getId()));
refList.getObjectRef().add(
new ObjectRefType(primaryContact.getId()));
refList.getObjectRef().add(
new ObjectRefType(federationAssociation.getId()));
RemoveObjectsRequest req = new RemoveObjectsRequest();
req.setId("Removing [" + registry.getId()
+ "] from the federation...");
req.setComment("Remove request to remove federation related objects");
req.setDeleteChildren(true);
req.setObjectRefList(refList);
statusHandler.info("Disconnecting from federation...");
try {
if (RegistryFederationManager.centralRegistry) {
lcm.removeObjects(req);
} else {
registrySoapServices.getLifecycleManagerServiceForHost(
ncfAddress).removeObjects(req);
}
statusHandler
.info("Registry disconnected from federation.");
} catch (MsgRegistryException e) {
statusHandler.error(
"Error while disconnecting from federation!", e);
}
}
} catch (Throwable e) {
statusHandler.error("Error leaving federation", e);
return false;
}
return true;
}
public static Set<String> getObjectTypes() {
@ -1422,4 +1509,9 @@ public class RegistryFederationManager implements RegistryInitializedListener {
DataDeliveryRESTServices dataDeliveryRestClient) {
this.dataDeliveryRestClient = dataDeliveryRestClient;
}
public static FederationProperties getFederationProperties() {
return federationProperties;
}
}

View file

@ -1,11 +1,11 @@
CREATE INDEX event_id_idx
ON ebxml.auditableevent_action
USING btree
USING hash
(auditableevent_id);
CREATE INDEX notification_id_idx
ON ebxml.notification_auditableevent
USING btree
USING hash
(notification_id);
CREATE INDEX objectreflist_id_idx
@ -15,57 +15,57 @@ CREATE INDEX objectreflist_id_idx
CREATE INDEX organization_id_email_idx
ON ebxml.organization_emailaddress
USING btree
USING hash
(organization_id);
CREATE INDEX organization_id_org_idx
ON ebxml.organization_organization
USING btree
USING hash
(org_id);
CREATE INDEX organization_id_address_idx
ON ebxml.organization_postaladdress
USING btree
USING hash
(organization_id);
CREATE INDEX organization_id_telephone_idx
ON ebxml.organization_telephonenumber
USING btree
USING hash
(organization_id);
CREATE INDEX person_id_email_idx
ON ebxml.person_emailaddress
USING btree
USING hash
(person_id);
CREATE INDEX person_id_address_idx
ON ebxml.person_postaladdress
USING btree
USING hash
(person_id);
CREATE INDEX person_id_telephone_idx
ON ebxml.person_telephonenumber
USING btree
USING hash
(person_id);
CREATE INDEX querydefinition_id_idx
ON ebxml.querydefinition_parameter
USING btree
USING hash
(querydefinition_id);
CREATE INDEX registryobject_id_classification_idx
ON ebxml.registryobject_classification
USING btree
USING hash
(registryobject_id);
CREATE INDEX registryobject_id_externalid_idx
ON ebxml.registryobject_externalidentifier
USING btree
USING hash
(registryobject_id);
CREATE INDEX registryobject_id_externallink_idx
ON ebxml.registryobject_externallink
USING btree
USING hash
(registryobject_id);
CREATE INDEX registryobjectlist_id_idx
@ -75,20 +75,245 @@ CREATE INDEX registryobjectlist_id_idx
CREATE INDEX service_id_idx
ON ebxml.service_serviceendpoint
USING btree
USING hash
(service_id);
CREATE INDEX subscription_id_idx
ON ebxml.subscription_deliveryinfo
USING btree
USING hash
(subscription_id);
CREATE INDEX taxonomyelement_id_idx
ON ebxml.taxonomyelementtype_classificationnode
USING btree
USING hash
(taxonomyelementtype_id);
CREATE INDEX value_id_idx
ON ebxml.value_value
USING btree
(value_id);
(value_id);
CREATE INDEX collectionvalue_id_idx
ON ebxml.value_value
USING btree
(collectionvalue_id);
CREATE INDEX objectref_id_idx
ON ebxml.objectref
USING hash
(id COLLATE pg_catalog."default");
CREATE INDEX objectref_key_idx
ON ebxml.objectref
USING hash
(key COLLATE pg_catalog."default");
CREATE INDEX objectreflist_key_idx
ON ebxml.objectreflist_objectref
USING hash
(objectref_key COLLATE pg_catalog."default");
CREATE INDEX slot_parent_id_idx
ON ebxml.slot
USING hash
(parent_id COLLATE pg_catalog."default");
CREATE INDEX action_eventtype_idx
ON ebxml.action
USING hash
(eventtype COLLATE pg_catalog."default");
CREATE INDEX auditableevent_timestamp_idx
ON ebxml.auditableevent
USING btree
("timestamp");
CREATE INDEX action_id_hash_idx
ON ebxml.action
USING hash
(id);
CREATE INDEX deliveryinfo_id_hash_idx
ON ebxml.deliveryinfo
USING hash
(id);
CREATE INDEX emailaddress_id_hash_idx
ON ebxml.emailaddress
USING hash
(id);
CREATE INDEX registryobject_id_hash_idx
ON ebxml.registryobject
USING hash
(id);
CREATE INDEX association_id_hash_idx
ON ebxml.association
USING hash
(id);
CREATE INDEX auditableevent_id_hash_idx
ON ebxml.auditableevent
USING hash
(id);
CREATE INDEX classification_id_hash_idx
ON ebxml.classification
USING hash
(id);
CREATE INDEX externalidentifier_id_hash_idx
ON ebxml.externalidentifier
USING hash
(id);
CREATE INDEX externallink_id_hash_idx
ON ebxml.externallink
USING hash
(id);
CREATE INDEX extrinsicobject_id_hash_idx
ON ebxml.extrinsicobject
USING hash
(id);
CREATE INDEX comment_id_hash_idx
ON ebxml.comment
USING hash
(id);
CREATE INDEX federation_id_hash_idx
ON ebxml.federation
USING hash
(id);
CREATE INDEX notification_id_hash_idx
ON ebxml.notification
USING hash
(id);
CREATE INDEX organization_id_hash_idx
ON ebxml.organization
USING hash
(id);
CREATE INDEX person_id_hash_idx
ON ebxml.person
USING hash
(id);
CREATE INDEX querydefinition_id_hash_idx
ON ebxml.querydefinition
USING hash
(id);
CREATE INDEX registrypackage_id_hash_idx
ON ebxml.registrypackage
USING hash
(id);
CREATE INDEX registry_id_hash_idx
ON ebxml.registry
USING hash
(id);
CREATE INDEX role_id_hash_idx
ON ebxml.role
USING hash
(id);
CREATE INDEX servicebinding_id_hash_idx
ON ebxml.servicebinding
USING hash
(id);
CREATE INDEX serviceendpoint_id_hash_idx
ON ebxml.serviceendpoint
USING hash
(id);
CREATE INDEX serviceinterface_id_hash_idx
ON ebxml.serviceinterface
USING hash
(id);
CREATE INDEX service_id_hash_idx
ON ebxml.service
USING hash
(id);
CREATE INDEX subscription_id_hash_idx
ON ebxml.subscription
USING hash
(id);
CREATE INDEX classificationnode_id_hash_idx
ON ebxml.classificationnode
USING hash
(id);
CREATE INDEX classificationscheme_id_hash_idx
ON ebxml.classificationscheme
USING hash
(id);
CREATE INDEX workflowaction_id_hash_idx
ON ebxml.workflowaction
USING hash
(id);
CREATE INDEX parameter_id_hash_idx
ON ebxml.parameter
USING hash
(id);
CREATE INDEX personname_id_hash_idx
ON ebxml.personname
USING hash
(id);
CREATE INDEX postaladdress_id_hash_idx
ON ebxml.postaladdress
USING hash
(id);
CREATE INDEX queryexpression_id_hash_idx
ON ebxml.queryexpression
USING hash
(id);
CREATE INDEX stringqueryexpression_id_hash_idx
ON ebxml.stringqueryexpression
USING hash
(id);
CREATE INDEX xmlqueryexpression_id_hash_idx
ON ebxml.xmlqueryexpression
USING hash
(id);
CREATE INDEX query_id_hash_idx
ON ebxml.query
USING hash
(id);
CREATE INDEX slot_id_hash_idx
ON ebxml.slot
USING hash
(id);
CREATE INDEX telephonenumber_id_hash_idx
ON ebxml.telephonenumber
USING hash
(id);

View file

@ -1,7 +1,7 @@
# The period which registry subscriptions are processed
ebxml-subscription-process.cron=0/20+*+*+*+*+?
# The period which the registry runs the garbage collection
ebxml-garbage-collect-process.cron=0/10+*+*+*+*+?
ebxml-garbage-collect-process.cron=*+0/5+*+*+*+?
# The period which adhoc subscriptions are cleaned, every 20 mins
adhocsubscription-process.cron=0+0/20+*+*+*+?
# When a federation synchonization is necessary, this is the number of threads

View file

@ -52,6 +52,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
* ------------ ---------- ----------- --------------------------
* 7/11/2013 1707 bphillip Initial implementation
* 7/29/2013 2191 bphillip Added executors to remove orphaned slots and expired events
* 1/15/2014 2613 bphillip Added Hibernate flush() call
* </pre>
*
* @author bphillip
@ -162,6 +163,7 @@ public class RegistryGarbageCollector {
@Override
public void runWithTransaction() {
eventDao.delete(event);
eventDao.flushAndClearSession();
}
}
}

View file

@ -90,6 +90,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
* 10/23/2013 1538 bphillip Added log message denoting when processing is complete and time duration
* 10/30/2013 1538 bphillip Changed to use non-static registry soap service client
* 12/2/2013 1829 bphillip Added getIdsFrom action method and changed how slots are added to objects
* 1/15/2014 2613 bphillip Added batching of notification update queries to reduce number of web service calls
*
* </pre>
*
@ -143,64 +144,75 @@ public class NotificationListenerImpl implements NotificationListener {
List<AuditableEventType> events = notification.getEvent();
// Process the received auditable events and add them to the
// appropriate
// list based on the action performed
List<String> actionList = new ArrayList<String>(events.size());
List<String> objIdList = new ArrayList<String>(events.size());
for (AuditableEventType event : events) {
List<ActionType> actions = event.getAction();
for (ActionType action : actions) {
String eventType = action.getEventType();
List<String> objectIds = getIdsFromAction(action);
if (objectIds.isEmpty()) {
statusHandler.info("Event " + event.getId()
+ " contains 0 affected objects ");
continue;
}
if (eventType.equals(ActionTypes.create)
|| eventType.equals(ActionTypes.update)) {
try {
SubmitObjectsRequest submitRequest = createSubmitObjectsRequest(
clientBaseURL, notification.getId(), objectIds,
Mode.CREATE_OR_REPLACE);
lcm.submitObjects(submitRequest);
} catch (MsgRegistryException e) {
throw new RuntimeException(
"Error creating objects in registry!", e);
} catch (EbxmlRegistryException e) {
throw new RuntimeException(
"Error creating submit objects request!", e);
}
} else if (eventType.equals(ActionTypes.delete)) {
ObjectRefListType refList = new ObjectRefListType();
for (String id : objectIds) {
RegistryObjectType object = registryObjectDao
.getById(id);
if (object != null) {
refList.getObjectRef().add(new ObjectRefType(id));
}
}
if (!CollectionUtil.isNullOrEmpty(refList.getObjectRef())) {
RemoveObjectsRequest request = new RemoveObjectsRequest(
"Remove Objects for notification ["
+ notification.getId() + "]",
"Notification delete object submission", null,
null, refList, false, true,
DeletionScope.DELETE_ALL);
try {
lcm.removeObjects(request);
} catch (MsgRegistryException e) {
throw new RuntimeException(
"Error creating remove objects request!", e);
}
}
} else {
statusHandler.info("Unknown event type [" + eventType
+ "] received in notification");
objIdList.addAll(objectIds);
for (int i = 0; i < objectIds.size(); i++) {
actionList.add(eventType);
}
}
}
int listSize = objIdList.size();
for (int i = 0; i < listSize;) {
List<String> insertIds = new ArrayList<String>();
while (i < listSize
&& (actionList.get(i).equals(ActionTypes.create) || actionList
.get(i).equals(ActionTypes.update))) {
insertIds.add(objIdList.get(i));
i++;
}
if (!insertIds.isEmpty()) {
try {
SubmitObjectsRequest submitRequest = createSubmitObjectsRequest(
clientBaseURL, notification.getId(), insertIds,
Mode.CREATE_OR_REPLACE);
lcm.submitObjects(submitRequest);
} catch (MsgRegistryException e) {
throw new RuntimeException(
"Error creating objects in registry!", e);
} catch (EbxmlRegistryException e) {
throw new RuntimeException(
"Error creating submit objects request!", e);
}
}
List<String> deleteIds = new ArrayList<String>();
while (i < listSize && actionList.get(i).equals(ActionTypes.delete)) {
deleteIds.add(objIdList.get(i));
i++;
}
if (!deleteIds.isEmpty()) {
ObjectRefListType refList = new ObjectRefListType();
for (String id : deleteIds) {
RegistryObjectType object = registryObjectDao.getById(id);
if (object != null) {
refList.getObjectRef().add(new ObjectRefType(id));
}
}
if (!CollectionUtil.isNullOrEmpty(refList.getObjectRef())) {
RemoveObjectsRequest request = new RemoveObjectsRequest(
"Remove Objects for notification ["
+ notification.getId() + "]",
"Notification delete object submission", null,
null, refList, false, true,
DeletionScope.DELETE_ALL);
try {
lcm.removeObjects(request);
} catch (MsgRegistryException e) {
throw new RuntimeException(
"Error creating remove objects request!", e);
}
}
}
}
registryDao.flushAndClearSession();
statusHandler.info("Processing notification id ["
+ notification.getId() + "] completed in "
+ (TimeUtil.currentTimeMillis() - startTime) + " ms");

View file

@ -80,6 +80,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
* to not create duplicate slots on objects
* 11/20/2013 2534 bphillip Moved method to get notification destinations to utility
* 12/9/2013 2613 bphillip Setting last run time of subscription now occurs before notification is sent
* 1/15/2014 2613 bphillip Added Hibernate flush and clear after subscription processing
* </pre>
*
* @author bphillip
@ -394,6 +395,8 @@ public class RegistrySubscriptionManager implements
statusHandler.error(
"Errors occurred while processing subscription ["
+ subscriptionName + "]", e);
} finally {
subscriptionDao.flushAndClearSession();
}
}