You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by da...@apache.org on 2018/02/16 09:52:18 UTC
[02/30] atlas git commit: ATLAS-2246: OMRS Connector API plus REST
and IGC Connector skeleton - 15th February 2018
http://git-wip-us.apache.org/repos/asf/atlas/blob/8a57e657/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/OMRSCohortRegistry.java
----------------------------------------------------------------------
diff --git a/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/OMRSCohortRegistry.java b/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/OMRSCohortRegistry.java
new file mode 100644
index 0000000..278ad10
--- /dev/null
+++ b/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/OMRSCohortRegistry.java
@@ -0,0 +1,1097 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.omrs.metadatahighway.cohortregistry;
+
+import org.apache.atlas.ocf.ffdc.OCFCheckedExceptionBase;
+import org.apache.atlas.ocf.properties.Connection;
+import org.apache.atlas.omrs.auditlog.OMRSAuditCode;
+import org.apache.atlas.omrs.auditlog.OMRSAuditLog;
+import org.apache.atlas.omrs.auditlog.OMRSAuditingComponent;
+import org.apache.atlas.omrs.eventmanagement.events.OMRSRegistryEventProcessor;
+import org.apache.atlas.omrs.metadatahighway.cohortregistry.store.OMRSCohortRegistryStore;
+import org.apache.atlas.omrs.metadatahighway.cohortregistry.store.properties.MemberRegistration;
+import org.apache.atlas.omrs.ffdc.exception.OMRSConfigErrorException;
+import org.apache.atlas.omrs.ffdc.exception.OMRSLogicErrorException;
+import org.apache.atlas.omrs.localrepository.repositorycontentmanager.OMRSTypeDefValidator;
+import org.apache.atlas.omrs.enterprise.connectormanager.OMRSConnectionConsumer;
+import org.apache.atlas.omrs.ffdc.OMRSErrorCode;
+import org.apache.atlas.omrs.ffdc.exception.OMRSRuntimeException;
+import org.apache.atlas.omrs.metadatacollection.properties.typedefs.TypeDefSummary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Date;
+
+
+/**
+ * OMRSCohortRegistry manages the local server's registration into a cohort and receives registration
+ * requests from other servers in the cohort. This management involves:
+ * <ul>
+ * <li>
+ * Sending and receiving registry events that contain registration information about the members
+ * of the cohort.
+ * </li>
+ * <li>
+ * Maintaining details of the local server's and other remote server's registration information
+ * in the cohort registry store to use for server restart.
+ * </li>
+ * <li>
+ * Interacting with the Local OMRS Connector and repository to verify that the type definitions
+ * (TypeDefs) used by other servers in the cohort are compatible with the local TypeDefs.
+ * </li>
+ * <li>
+ * Configuring the federation services (OMRS Federation Manager and Enterprise OMRS Connector) with
+ * information about the other servers in the cohort as they register and unregister from the
+ * cohort.
+ * </li>
+ * </ul>
+ * Within a server, there is a single instance of the cohort registry for each cohort that the server joins.
+ */
+public class OMRSCohortRegistry implements OMRSRegistryEventProcessor
+{
+ /*
+ * Local name of the cohort - used for messages rather than being part of the protocol.
+ */
+ private String cohortName = null;
+
+ /*
+ * These variables describe the local server's properties.
+ */
+ private String localMetadataCollectionId = null;
+ private Connection localRepositoryRemoteConnection = null;
+ private String localServerName = null;
+ private String localServerType = null;
+ private String localOrganizationName = null;
+
+ /*
+ * The registry store is used to save information about the members of the open metadata repository cohort.
+ */
+ private OMRSCohortRegistryStore registryStore = null;
+
+ /*
+ * The event publisher is used to send events to the rest of the open metadata repository cohort.
+ */
+ private OMRSRegistryEventProcessor outboundRegistryEventProcessor = null;
+
+ /*
+ * The connection consumer supports components such as the EnterpriseOMRSRepositoryConnector that need to maintain a
+ * list of remote partners that are part of the open metadata repository cohort.
+ */
+ private OMRSConnectionConsumer connectionConsumer = null;
+
+ /*
+ * The typeDef manager provides the cohort registry with details of the TypeDefs supported by the local
+ * and also validates the compatibility of TypeDefs from other members of the open metadata repository cohort.
+ */
+ private OMRSTypeDefValidator typeDefValidator = null;
+
+ /*
+ * The audit log provides a verifiable record of the membership of the open metadata repository cohort and the
+ * metadata exchange activity they are involved in. The Logger is for standard debug.
+ */
+ private static final OMRSAuditLog auditLog = new OMRSAuditLog(OMRSAuditingComponent.COHORT_REGISTRY);
+ private static final Logger log = LoggerFactory.getLogger(OMRSCohortRegistry.class);
+
+
+ /**
+ * Default constructor that relies on the initialization of variables in the declaration.
+ */
+ public OMRSCohortRegistry()
+ {
+ }
+
+
+ /**
+ * Validate that any metadata collection id previously used by the local server to register with the
+ * open metadata repository cohort matches the local metadata collection id passed in the configuration
+ * properties.
+ *
+ * @param configuredLocalMetadataCollectionId - configured value for the local metadata collection id - may be null
+ * if no local repository.
+ */
+ private void validateLocalMetadataCollectionId(String configuredLocalMetadataCollectionId)
+ {
+ String methodName = "validateLocalMetadataCollectionId()";
+
+ if (this.registryStore == null)
+ {
+ /*
+ * Throw exception as the cohort registry store is not available.
+ */
+ OMRSErrorCode errorCode = OMRSErrorCode.NULL_REGISTRY_STORE;
+ String errorMessage = errorCode.getErrorMessageId()
+ + errorCode.getFormattedErrorMessage(cohortName);
+
+ throw new OMRSLogicErrorException(errorCode.getHTTPErrorCode(),
+ this.getClass().getName(),
+ methodName,
+ errorMessage,
+ errorCode.getSystemAction(),
+ errorCode.getUserAction());
+ }
+
+ MemberRegistration localRegistration = registryStore.retrieveLocalRegistration();
+
+ if (localRegistration != null)
+ {
+ String storedLocalMetadataCollectionId = localRegistration.getMetadataCollectionId();
+
+ if (storedLocalMetadataCollectionId != null)
+ {
+ /*
+ * There is a stored local metadata collection id which is going to be used. There is a consistency check
+ * to ensure this stored local Id is the same as the configured local metadata collection id.
+ *
+ * If it is not the same, the administrator has changed the configured value after the server
+ * registered with the cohort. The message on the audit log explains that the new value will be
+ * ignored until the local repository is un-registered with the old metadata collection id and then it
+ * can be registered with the new metadata collection Id.
+ */
+
+ if (!storedLocalMetadataCollectionId.equals(configuredLocalMetadataCollectionId))
+ {
+ if (configuredLocalMetadataCollectionId == null)
+ {
+ /*
+ * The change in the configuration is to remove the local repository. This means
+ * the local server should simply unregister from the cohort.
+ */
+ this.unRegisterLocalRepositoryWithCohort(localRegistration);
+ registryStore.removeLocalRegistration();
+
+ }
+ else
+ {
+ /*
+ * The configured value is different from the value used to register with this cohort.
+ * This is a situation that could potentially damage the metadata integrity across the cohort.
+ * Hence the exception.
+ */
+ OMRSErrorCode errorCode = OMRSErrorCode.INVALID_LOCAL_METADATA_COLLECTION_ID;
+ String errorMessage = errorCode.getErrorMessageId()
+ + errorCode.getFormattedErrorMessage(cohortName,
+ localServerName,
+ storedLocalMetadataCollectionId,
+ configuredLocalMetadataCollectionId);
+
+ throw new OMRSConfigErrorException(errorCode.getHTTPErrorCode(),
+ this.getClass().getName(),
+ methodName,
+ errorMessage,
+ errorCode.getSystemAction(),
+ errorCode.getUserAction());
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Initialize the cohort registry object. The parameters passed control its behavior.
+ *
+ * @param cohortName - the name of the cohort that this cohort registry is communicating with.
+ * @param localMetadataCollectionId - configured value for the local metadata collection id - may be null
+ * if no local repository.
+ * @param localRepositoryRemoteConnection - the connection properties for a connector that can call this
+ * server from a remote server.
+ * @param localServerName - the name of the local server. It is a descriptive name for informational purposes.
+ * @param localServerType - the type of the local server. It is a descriptive name for informational purposes.
+ * @param localOrganizationName - the name of the organization that owns the local server/repository.
+ * It is a descriptive name for informational purposes.
+ * @param registryEventProcessor - used to send outbound registry events to the cohort.
+ * @param cohortRegistryStore - the cohort registry store where details of members of the cohort are kept.
+ * @param typeDefValidator - TypeDef validator is used to validate typedefs across membership of the open
+ * metadata repository cohort. If it is null then no TypeDef validation occurs.
+ * @param connectionConsumer - The connection consumer is a component interested in maintaining details of the
+ * connections to each of the members of the open metadata repository cohort. If it is
+ * null, the cohort registry does not publish connections for members of the open
+ * metadata repository cohort.
+ */
+ public void initialize(String cohortName,
+ String localMetadataCollectionId,
+ Connection localRepositoryRemoteConnection,
+ String localServerName,
+ String localServerType,
+ String localOrganizationName,
+ OMRSRegistryEventProcessor registryEventProcessor,
+ OMRSCohortRegistryStore cohortRegistryStore,
+ OMRSTypeDefValidator typeDefValidator,
+ OMRSConnectionConsumer connectionConsumer)
+ {
+ String actionDescription = "Initialize cohort registry";
+
+ if (cohortRegistryStore == null)
+ {
+ OMRSErrorCode errorCode = OMRSErrorCode.NULL_REGISTRY_STORE;
+ String errorMessage = errorCode.getErrorMessageId()
+ + errorCode.getFormattedErrorMessage(cohortName);
+
+ throw new OMRSLogicErrorException(errorCode.getHTTPErrorCode(),
+ this.getClass().getName(),
+ actionDescription,
+ errorMessage,
+ errorCode.getSystemAction(),
+ errorCode.getUserAction());
+ }
+ this.registryStore = cohortRegistryStore;
+
+ /*
+ * Save the cohort name for messages and the registry event processor for sending outbound events.
+ */
+ this.cohortName = cohortName;
+ this.outboundRegistryEventProcessor = registryEventProcessor;
+
+ /*
+ * Verify that the configured local metadata collection Id matches the one stored in the registry store.
+ * This will throw an exception if there are unresolvable differences.
+ */
+ this.validateLocalMetadataCollectionId(localMetadataCollectionId);
+
+ /*
+ * Save the TypeDef validator. This object is able to generate the list of TypeDef
+ * summaries supported by this repository and validate the TypeDef summaries received
+ * from the remote members of the open metadata repository cluster.
+ */
+ this.typeDefValidator = typeDefValidator;
+
+ /*
+ * Save the connection consumer. This component needs details of the current connections it should use
+ * to contact various members of the cluster (including the local server). It needs an initial
+ * upload of the members's connections and then ongoing notifications for any changes in the membership.
+ */
+ this.connectionConsumer = connectionConsumer;
+
+ /*
+ * Save the connections to the local repository. The localRepositoryRemoteConnection is used
+ * in the registration request that this repository sends out.
+ */
+ this.localRepositoryRemoteConnection = localRepositoryRemoteConnection;
+
+ /*
+ * Save information about the local server
+ */
+ this.localServerName = localServerName;
+ this.localServerType = localServerType;
+ this.localOrganizationName = localOrganizationName;
+ }
+
+
+ /**
+ * A new server needs to register the metadataCollectionId for its metadata repository with the other servers in the
+ * open metadata repository. It only needs to do this once and uses a timestamp to record that the registration
+ * event has been sent.
+ *
+ * If the server has already registered in the past, it does not need to take any action.
+ */
+ public void connectToCohort()
+ {
+ if (registryStore == null)
+ {
+ /*
+ * Throw exception as the cohort registry store is not available.
+ */
+ String methodName = "connectToCohort()";
+
+ OMRSErrorCode errorCode = OMRSErrorCode.NULL_REGISTRY_STORE;
+ String errorMessage = errorCode.getErrorMessageId() + errorCode.getFormattedErrorMessage();
+
+ throw new OMRSRuntimeException(errorCode.getHTTPErrorCode(),
+ this.getClass().getName(),
+ methodName,
+ errorMessage,
+ errorCode.getSystemAction(),
+ errorCode.getUserAction());
+ }
+
+
+ /*
+ * Extract member registration information from the cohort registry store. If there is
+ * no local registration, it means the local repository is not currently registered with the metadata
+ * repository cohort.
+ */
+ MemberRegistration localRegistration = registryStore.retrieveLocalRegistration();
+
+ if (localRegistration == null)
+ {
+ localRegistration = new MemberRegistration();
+ }
+
+
+ /*
+ * Fill in the local registration with details from the caller. Any value from the local repository
+ * can change except the localMetadataCollectionId and this value has already been validated.
+ */
+ localRegistration.setMetadataCollectionId(localMetadataCollectionId);
+ localRegistration.setServerName(localServerName);
+ localRegistration.setServerType(localServerType);
+ localRegistration.setOrganizationName(localOrganizationName);
+ localRegistration.setRepositoryConnection(localRepositoryRemoteConnection);
+
+ if (localMetadataCollectionId == null)
+ {
+ /*
+ * If the local metadata collection Id is null it means there is no local repository. No registration
+ * is required but the cohort registry sends a registration refresh request to ensure it has a complete
+ * list of the remote members for the connection consumer. The connection consumer will be null
+ * if enterprise access is disabled.
+ */
+ if (connectionConsumer != null)
+ {
+ this.requestReRegistrationFromCohort(localRegistration);
+ }
+ }
+ else if (localRegistration.getRegistrationTime() == null)
+ {
+ /*
+ * This repository has never registered with the open metadata repository cohort, so send registration
+ * request.
+ */
+ localRegistration.setRegistrationTime(new Date());
+
+ if (this.registerLocalRepositoryWithCohort(localRegistration))
+ {
+ /*
+ * Successfully registered so save the local registration to the registry store.
+ */
+ registryStore.saveLocalRegistration(localRegistration);
+ }
+ }
+ else
+ {
+ /*
+ * Successfully registered already - save the local registration to the registry store.
+ * in case some of the server details (name, type, organization name) have changed.
+ */
+ registryStore.saveLocalRegistration(localRegistration);
+
+ /*
+ * No registration is required but the cohort registry sends a registration refresh request to
+ * ensure it has a complete list of the remote members for the connection consumer.
+ * The connection consumer will be null if enterprise access is disabled.
+ */
+ if (connectionConsumer != null)
+ {
+ this.requestReRegistrationFromCohort(localRegistration);
+ }
+ }
+
+ /*
+ * Now read the remote registrations from the registry store and publish them to the connection consumer.
+ * The connection consumer will be null if enterprise access is disabled.
+ */
+ if (connectionConsumer != null)
+ {
+ /*
+ * Extract remote member registrations from the cohort registry store and register each one with the
+ * connection consumer.
+ */
+ ArrayList<MemberRegistration> remoteRegistrations = registryStore.retrieveRemoteRegistrations();
+
+ if (remoteRegistrations != null)
+ {
+ for (MemberRegistration remoteMember : remoteRegistrations)
+ {
+ if (remoteMember != null)
+ {
+ this.registerRemoteConnectionWithConsumer(remoteMember.getMetadataCollectionId(),
+ remoteMember.getServerName(),
+ remoteMember.getRepositoryConnection());
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Close the connection to the registry store.
+ *
+ * @param permanent boolean flag indicating whether the disconnection is permanent or not. If it is set
+ * to true, the OMRS Cohort will remove all information about the cohort from the
+ * cohort registry store.
+ */
+ public void disconnectFromCohort(boolean permanent)
+ {
+ final String actionDescription = "Disconnect from Cohort";
+
+ if (registryStore != null)
+ {
+ if (permanent)
+ {
+ MemberRegistration localRegistration = registryStore.retrieveLocalRegistration();
+
+ OMRSAuditCode auditCode = OMRSAuditCode.COHORT_PERMANENTLY_DISCONNECTING;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ if (localRegistration != null)
+ {
+ this.unRegisterLocalRepositoryWithCohort(localRegistration);
+ }
+
+ registryStore.clearAllRegistrations();
+
+ if (connectionConsumer != null)
+ {
+ connectionConsumer.removeCohort(cohortName);
+ }
+ }
+ else
+ {
+ OMRSAuditCode auditCode = OMRSAuditCode.COHORT_DISCONNECTING;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+ }
+
+ registryStore.close();
+ }
+ }
+
+
+ /**
+ * Send a registration event to the open metadata repository cohort. This means the
+ * server has never registered with the cohort before.
+ *
+ * @param localRegistration - details of the local server that are needed to build the event
+ * @return boolean indicating whether the repository registered successfully or not.
+ */
+ private boolean registerLocalRepositoryWithCohort(MemberRegistration localRegistration)
+ {
+ final String actionDescription = "Registering with cohort";
+
+ OMRSAuditCode auditCode = OMRSAuditCode.REGISTERED_WITH_COHORT;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName, localMetadataCollectionId),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ ArrayList<TypeDefSummary> typeDefSummaries = null;
+
+ if (typeDefValidator != null)
+ {
+ typeDefSummaries = typeDefValidator.getLocalTypeDefs();
+ }
+
+ return outboundRegistryEventProcessor.processRegistrationEvent(cohortName,
+ localRegistration.getMetadataCollectionId(),
+ localRegistration.getServerName(),
+ localRegistration.getServerType(),
+ localRegistration.getOrganizationName(),
+ localRegistration.getRegistrationTime(),
+ localRegistration.getRepositoryConnection(),
+ typeDefSummaries);
+ }
+
+
+ /**
+ * Request that the remote members of the cohort send details of their registration to enable the local
+ * server to ensure it has details of every member. There are two use cases. It may have missed a
+ * registration event from a remote member because it was not online for some time.
+ * Alternatively, it may not have a local repository and so can not trigger the reRegistration events
+ * with its own registration events.
+ *
+ * @param localRegistration - information needed to sent the refresh request
+ * @return boolean flag indicating whether it worked or not.
+ */
+ private boolean requestReRegistrationFromCohort(MemberRegistration localRegistration)
+ {
+ final String actionDescription = "Re-registering with cohort";
+
+ OMRSAuditCode auditCode = OMRSAuditCode.RE_REGISTERED_WITH_COHORT;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ return outboundRegistryEventProcessor.processRegistrationRefreshRequest(cohortName,
+ localRegistration.getServerName(),
+ localRegistration.getServerType(),
+ localRegistration.getOrganizationName());
+ }
+
+
+ /**
+ * Unregister from the Cohort.
+ *
+ * @param localRegistration - details of the local registration
+ * @return boolean indicating whether the request was successful of not.
+ */
+ private boolean unRegisterLocalRepositoryWithCohort(MemberRegistration localRegistration)
+ {
+ final String actionDescription = "Unregistering from cohort";
+
+ OMRSAuditCode auditCode = OMRSAuditCode.UNREGISTERING_FROM_COHORT;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName, localMetadataCollectionId),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ return outboundRegistryEventProcessor.processUnRegistrationEvent(cohortName,
+ localRegistration.getMetadataCollectionId(),
+ localRegistration.getServerName(),
+ localRegistration.getServerType(),
+ localRegistration.getOrganizationName());
+ }
+
+
+ /**
+ * Register a new remote connection with the OMRSConnectionConsumer. If there is a problem with the
+ * remote connection, a bad connection registry event is sent to the remote repository.
+ *
+ * @param remoteMetadataCollectionId - id of the remote repository
+ * @param remoteServerName - name of the remote server.
+ * @param remoteRepositoryConnection - connection used to create a connector to call the remote repository.
+ */
+ private void registerRemoteConnectionWithConsumer(String remoteMetadataCollectionId,
+ String remoteServerName,
+ Connection remoteRepositoryConnection)
+ {
+ final String actionDescription = "Receiving registration request";
+ OMRSAuditCode auditCode = OMRSAuditCode.OUTGOING_BAD_CONNECTION;
+
+ if (connectionConsumer != null)
+ {
+ /*
+ * An exception is thrown if the remote connection is bad.
+ */
+ try
+ {
+ connectionConsumer.addRemoteConnection(cohortName,
+ remoteMetadataCollectionId,
+ remoteRepositoryConnection);
+ }
+ catch (OCFCheckedExceptionBase error)
+ {
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName,
+ remoteRepositoryConnection.getConnectionName(),
+ remoteServerName,
+ remoteMetadataCollectionId),
+ error.getErrorMessage(),
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ if (outboundRegistryEventProcessor != null)
+ {
+ outboundRegistryEventProcessor.processBadConnectionEvent(cohortName,
+ localMetadataCollectionId,
+ localServerName,
+ localServerType,
+ localOrganizationName,
+ remoteMetadataCollectionId,
+ remoteRepositoryConnection,
+ error.getErrorMessage());
+ }
+ }
+ catch (Throwable error)
+ {
+ String formattedLogMessage = auditCode.getFormattedLogMessage(cohortName,
+ remoteRepositoryConnection.getConnectionName(),
+ remoteServerName,
+ remoteMetadataCollectionId);
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ formattedLogMessage,
+ error.toString(),
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ if (outboundRegistryEventProcessor != null)
+ {
+ outboundRegistryEventProcessor.processBadConnectionEvent(cohortName,
+ localMetadataCollectionId,
+ localServerName,
+ localServerType,
+ localOrganizationName,
+ remoteMetadataCollectionId,
+ remoteRepositoryConnection,
+ auditCode.getLogMessageId() + formattedLogMessage);
+ }
+ }
+ }
+ }
+
+ /**
+ * Unregister a remote connection from the OMRSConnectionConsumer.
+ *
+ * @param remoteMetadataCollectionId - id of the remote repository
+ */
+ private void unRegisterRemoteConnectionWithConsumer(String remoteMetadataCollectionId)
+ {
+ if (connectionConsumer != null)
+ {
+ connectionConsumer.removeRemoteConnection(cohortName,
+ remoteMetadataCollectionId);
+ }
+ }
+
+
+ /*
+ * =============================
+ * OMRSRegistryEventProcessor
+ */
+
+ /**
+ * Introduces a new server/repository to the metadata repository cohort.
+ *
+ * @param sourceName - name of the source of the event. It may be the cohort name for incoming events or the
+ * local repository, or event mapper name.
+ * @param originatorMetadataCollectionId - unique identifier for the metadata collection that is registering with the cohort.
+ * @param originatorServerName - name of the server that the event came from.
+ * @param originatorServerType - type of server that the event came from.
+ * @param originatorOrganizationName - name of the organization that owns the server that sent the event.
+ * @param registrationTimestamp - the time that the server/repository issued the registration request.
+ * @param remoteConnection - the Connection properties for the connector used to call the registering server.
+ * @param typeDefList - the list of TypeDefs supported by the registering server/repository.
+ */
+ public boolean processRegistrationEvent(String sourceName,
+ String originatorMetadataCollectionId,
+ String originatorServerName,
+ String originatorServerType,
+ String originatorOrganizationName,
+ Date registrationTimestamp,
+ Connection remoteConnection,
+ ArrayList<TypeDefSummary> typeDefList)
+ {
+ final String actionDescription = "Receiving Registration event";
+
+ if (registryStore != null)
+ {
+ /*
+ * Store information about the remote repository in the cohort registry store.
+ */
+ MemberRegistration remoteRegistration = new MemberRegistration();
+
+ remoteRegistration.setMetadataCollectionId(originatorMetadataCollectionId);
+ remoteRegistration.setServerName(originatorServerName);
+ remoteRegistration.setServerType(originatorServerType);
+ remoteRegistration.setOrganizationName(originatorOrganizationName);
+ remoteRegistration.setRegistrationTime(registrationTimestamp);
+ remoteRegistration.setRepositoryConnection(remoteConnection);
+
+ registryStore.saveRemoteRegistration(remoteRegistration);
+
+ if (remoteConnection != null)
+ {
+ /*
+ * Pass the new remote connection to the connection consumer.
+ */
+ this.registerRemoteConnectionWithConsumer(originatorMetadataCollectionId,
+ originatorServerName,
+ remoteConnection);
+ }
+
+ OMRSAuditCode auditCode = OMRSAuditCode.NEW_MEMBER_IN_COHORT;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName,
+ originatorServerName,
+ originatorMetadataCollectionId),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ /*
+ * Check for incompatible TypeDefs occurring between this local repository and the new member.
+ * Incompatible TypeDefs are logged and managed by the typeDefValidator.
+ */
+ if ((typeDefValidator != null) && (typeDefList != null))
+ {
+ typeDefValidator.validateAgainstLocalTypeDefs(sourceName, typeDefList);
+ }
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ /**
+ * Requests that the other servers in the cohort send re-registration events.
+ *
+ * @param sourceName - name of the source of the event. It may be the cohort name for incoming events or the
+ * local repository, or event mapper name.
+ * @param originatorServerName - name of the server that the event came from.
+ * @param originatorServerType - type of server that the event came from.
+ * @param originatorOrganizationName - name of the organization that owns the server that sent the event.
+ */
+ public boolean processRegistrationRefreshRequest(String sourceName,
+ String originatorServerName,
+ String originatorServerType,
+ String originatorOrganizationName)
+ {
+ final String actionDescription = "Receiving Registration Refresh event";
+
+ if (registryStore != null)
+ {
+ MemberRegistration localRegistration = registryStore.retrieveLocalRegistration();
+
+ if (localRegistration != null)
+ {
+ ArrayList<TypeDefSummary> typeDefSummaries = null;
+
+ if (typeDefValidator != null)
+ {
+ typeDefSummaries = typeDefValidator.getLocalTypeDefs();
+ }
+
+ OMRSAuditCode auditCode = OMRSAuditCode.REFRESHING_REGISTRATION_WITH_COHORT;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName,
+ localMetadataCollectionId,
+ originatorServerName),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ return outboundRegistryEventProcessor.processReRegistrationEvent(cohortName,
+ localRegistration.getMetadataCollectionId(),
+ localRegistration.getServerName(),
+ localRegistration.getServerType(),
+ localRegistration.getOrganizationName(),
+ localRegistration.getRegistrationTime(),
+ localRegistration.getRepositoryConnection(),
+ typeDefSummaries);
+ }
+ else
+ {
+ return true;
+ }
+ }
+ else
+ {
+ OMRSAuditCode auditCode = OMRSAuditCode.MISSING_MEMBER_REGISTRATION;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(originatorServerName,
+ cohortName),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ return false;
+ }
+ }
+
+
+ /**
+ * Refreshes the other servers in the cohort with the originator server's registration.
+ *
+ * @param sourceName - name of the source of the event. It may be the cohort name for incoming events or the
+ * local repository, or event mapper name.
+ * @param originatorMetadataCollectionId - unique identifier for the metadata collection that is registering with the cohort.
+ * @param originatorServerName - name of the server that the event came from.
+ * @param originatorServerType - type of server that the event came from.
+ * @param originatorOrganizationName - name of the organization that owns the server that sent the event.
+ * @param registrationTimestamp - the time that the server/repository first registered with the cohort.
+ * @param remoteConnection - the Connection properties for the connector used to call the registering server.
+ * @param typeDefList - the list of TypeDefs supported by the registering server/repository.
+ */
+ public boolean processReRegistrationEvent(String sourceName,
+ String originatorMetadataCollectionId,
+ String originatorServerName,
+ String originatorServerType,
+ String originatorOrganizationName,
+ Date registrationTimestamp,
+ Connection remoteConnection,
+ ArrayList<TypeDefSummary> typeDefList)
+ {
+ final String actionDescription = "Receiving ReRegistration event";
+
+ if (registryStore != null)
+ {
+ /*
+ * Store information about the remote repository in the cohort registry store. If the
+ * repository is already stored in the registry store, its entry is refreshed.
+ */
+ MemberRegistration remoteRegistration = new MemberRegistration();
+
+ remoteRegistration.setMetadataCollectionId(originatorMetadataCollectionId);
+ remoteRegistration.setServerName(originatorServerName);
+ remoteRegistration.setServerType(originatorServerType);
+ remoteRegistration.setOrganizationName(originatorOrganizationName);
+ remoteRegistration.setRegistrationTime(registrationTimestamp);
+ remoteRegistration.setRepositoryConnection(remoteConnection);
+
+ registryStore.saveRemoteRegistration(remoteRegistration);
+
+ if (remoteConnection != null)
+ {
+ /*
+ * Pass the new remote connection to the connection consumer. It may have been updated since
+ * the last registration request was received.
+ */
+ this.registerRemoteConnectionWithConsumer(originatorMetadataCollectionId,
+ originatorServerName,
+ remoteConnection);
+ }
+
+ OMRSAuditCode auditCode = OMRSAuditCode.REFRESHED_MEMBER_IN_COHORT;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName,
+ originatorServerName,
+ originatorMetadataCollectionId),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ /*
+ * Check for incompatible TypeDefs occurring between this local repository and the new member.
+ * The TypeDefManager will drive any error handling.
+ */
+ if ((typeDefValidator != null) && (typeDefList != null))
+ {
+ typeDefValidator.validateAgainstLocalTypeDefs(sourceName, typeDefList);
+ }
+
+ return true;
+ }
+ else
+ {
+ OMRSAuditCode auditCode = OMRSAuditCode.MISSING_MEMBER_REGISTRATION;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(originatorServerName,
+ cohortName),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ return false;
+ }
+ }
+
+
+ /**
+ * A server/repository is being removed from the metadata repository cohort.
+ *
+ * @param sourceName - name of the source of the event. It may be the cohort name for incoming events or the
+ * local repository, or event mapper name.
+ * @param originatorMetadataCollectionId - metadata collectionId of originator.
+ * @param originatorServerName - name of the server that the event came from.
+ * @param originatorServerType - type of server that the event came from.
+ * @param originatorOrganizationName - name of the organization that owns the server that sent the event.
+ */
+ public boolean processUnRegistrationEvent(String sourceName,
+ String originatorMetadataCollectionId,
+ String originatorServerName,
+ String originatorServerType,
+ String originatorOrganizationName)
+ {
+ final String actionDescription = "Receiving Unregistration event";
+
+ if (registryStore != null)
+ {
+
+ /*
+ * Remove the remote member from the registry store.
+ */
+ registryStore.removeRemoteRegistration(originatorMetadataCollectionId);
+
+ /*
+ * Pass the new remote connection to the connection consumer.
+ */
+ this.unRegisterRemoteConnectionWithConsumer(originatorMetadataCollectionId);
+
+ OMRSAuditCode auditCode = OMRSAuditCode.MEMBER_LEFT_COHORT;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(originatorServerName,
+ originatorMetadataCollectionId,
+ cohortName),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ return true;
+ }
+ else
+ {
+ OMRSAuditCode auditCode = OMRSAuditCode.MISSING_MEMBER_REGISTRATION;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(originatorServerName,
+ cohortName),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+
+ return false;
+ }
+ }
+
+
+ /**
+ * There is more than one member of the open metadata repository cohort that is using the same metadata
+ * collection Id. This means that their metadata instances can be updated in more than one server and their
+ * is a potential for data integrity issues.
+ *
+ * @param sourceName - name of the source of the event. It may be the cohort name for incoming events or the
+ * local repository, or event mapper name.
+ * @param originatorMetadataCollectionId - metadata collectionId of originator.
+ * @param originatorServerName - name of the server that the event came from.
+ * @param originatorServerType - type of server that the event came from.
+ * @param originatorOrganizationName - name of the organization that owns the server that sent the event.
+ * @param conflictingMetadataCollectionId - unique identifier for the metadata collection that is registering with the cohort.
+ * @param errorMessage - details of the conflict
+ */
+ public void processConflictingCollectionIdEvent(String sourceName,
+ String originatorMetadataCollectionId,
+ String originatorServerName,
+ String originatorServerType,
+ String originatorOrganizationName,
+ String conflictingMetadataCollectionId,
+ String errorMessage)
+ {
+ if (conflictingMetadataCollectionId != null)
+ {
+ final String actionDescription = "Receiving Conflicting Metadata Collection Id event";
+
+ if (conflictingMetadataCollectionId.equals(localMetadataCollectionId))
+ {
+ OMRSAuditCode auditCode = OMRSAuditCode.INCOMING_CONFLICTING_LOCAL_METADATA_COLLECTION_ID;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName,
+ originatorServerName,
+ originatorMetadataCollectionId,
+ conflictingMetadataCollectionId),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+ }
+ else
+ {
+ OMRSAuditCode auditCode = OMRSAuditCode.INCOMING_CONFLICTING_METADATA_COLLECTION_ID;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName,
+ conflictingMetadataCollectionId),
+ null,
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+ }
+ }
+ }
+
+
+ /**
+ * A connection to one of the members of the open metadata repository cohort is not usable by one of the members.
+ *
+ * @param sourceName - name of the source of the event. It may be the cohort name for incoming events or the
+ * local repository, or event mapper name.
+ * @param originatorMetadataCollectionId - metadata collectionId of originator.
+ * @param originatorServerName - name of the server that the event came from.
+ * @param originatorServerType - type of server that the event came from.
+ * @param originatorOrganizationName - name of the organization that owns the server that sent the event.
+ * @param targetMetadataCollectionId - Id for the repository with the bad remote connection.
+ * @param remoteRepositoryConnection - the Connection properties for the connector used to call the registering server.
+ * @param errorMessage - details of the error that occurs when the connection is used.
+ */
+ public void processBadConnectionEvent(String sourceName,
+ String originatorMetadataCollectionId,
+ String originatorServerName,
+ String originatorServerType,
+ String originatorOrganizationName,
+ String targetMetadataCollectionId,
+ Connection remoteRepositoryConnection,
+ String errorMessage)
+ {
+ if (targetMetadataCollectionId != null)
+ {
+ if (targetMetadataCollectionId.equals(localMetadataCollectionId))
+ {
+ /*
+ * The event is directed to this server.
+ */
+ final String actionDescription = "Receiving Bad Connection event";
+ OMRSAuditCode auditCode = OMRSAuditCode.INCOMING_BAD_CONNECTION;
+ auditLog.logRecord(actionDescription,
+ auditCode.getLogMessageId(),
+ auditCode.getSeverity(),
+ auditCode.getFormattedLogMessage(cohortName,
+ originatorServerName,
+ originatorMetadataCollectionId,
+ remoteRepositoryConnection.getConnectionName()),
+ remoteRepositoryConnection.toString(),
+ auditCode.getSystemAction(),
+ auditCode.getUserAction());
+ }
+ }
+ }
+
+
+ /**
+ * Standard toString method.
+ *
+ * @return JSON style description of variables.
+ */
+ @Override
+ public String toString()
+ {
+ return "OMRSCohortRegistry{" +
+ "cohortName='" + cohortName + '\'' +
+ ", localMetadataCollectionId='" + localMetadataCollectionId + '\'' +
+ ", localRepositoryRemoteConnection=" + localRepositoryRemoteConnection +
+ ", localServerName='" + localServerName + '\'' +
+ ", localServerType='" + localServerType + '\'' +
+ ", localOrganizationName='" + localOrganizationName + '\'' +
+ ", registryStore=" + registryStore +
+ ", outboundRegistryEventProcessor=" + outboundRegistryEventProcessor +
+ ", connectionConsumer=" + connectionConsumer +
+ ", typeDefValidator=" + typeDefValidator +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/8a57e657/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStore.java
----------------------------------------------------------------------
diff --git a/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStore.java b/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStore.java
new file mode 100644
index 0000000..1539c3c
--- /dev/null
+++ b/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStore.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.omrs.metadatahighway.cohortregistry.store;
+
+import org.apache.atlas.omrs.metadatahighway.cohortregistry.store.properties.MemberRegistration;
+
+import java.util.ArrayList;
+
+
+/**
+ * OMRSCohortRegistryStore is a connector to a repository that can store registration information for a cohort registry.
+ * Each repository store serves a single repository. It supports:
+ * <ul>
+ * <li>
+ * One LocalRegistration that describes information about the local repository and its registration with
+ * the metadata repository cohort. Note: the local registration is null if there is no local repository.
+ * </li>
+ * <li>
+ * None to many RemoteRegistrations. There is a RemoteRegistration for each of the other repositories
+ * registered in the metadata repository cohort.
+ * </li>
+ * </ul>
+ */
+public interface OMRSCohortRegistryStore
+{
+ /**
+ * Save the local registration to the cohort registry store. This provides details of the local repository's
+ * registration with the metadata repository cohort.
+ * Any previous local registration information is overwritten.
+ *
+ * @param localRegistration - details of the local repository's registration with the metadata cohort.
+ */
+ void saveLocalRegistration(MemberRegistration localRegistration);
+
+
+ /**
+ * Retrieve details of the local registration from the cohort registry store. A null may be returned if the
+ * local registration information has not been saved (typically because this is a new server instance).
+ *
+ * @return MemberRegistration object containing details for the local repository's registration with the
+ * metadata cohort
+ */
+ MemberRegistration retrieveLocalRegistration();
+
+
+ /**
+ * Remove details of the local registration from the cohort registry store. This is used when the local
+ * repository unregisters from the open metadata repository cohort.
+ */
+ void removeLocalRegistration();
+
+
+ /**
+ * Save details of a remote registration. This contains details of one of the other repositories in the
+ * metadata repository cohort. If a remote registration already exists, it is over-written.
+ *
+ * @param remoteRegistration - details of a remote repository in the metadata repository cohort.
+ */
+ void saveRemoteRegistration(MemberRegistration remoteRegistration);
+
+
+ /**
+ * Return a list of all of the remote metadata repositories registered in the metadata repository cohort.
+ *
+ * @return List of member registrations for remote servers/repositories
+ */
+ ArrayList<MemberRegistration> retrieveRemoteRegistrations();
+
+
+ /**
+ * Return the registration information for a specific metadata repository, identified by its repository's
+ * metadata collection Id. If the metadata collection Id is not recognized then null is returned.
+ *
+ * @param metadataCollectionId - unique identifier for the repository's metadata collection.
+ * @return MemberRegistration object containing details of the remote metadata repository.
+ */
+ MemberRegistration retrieveRemoteRegistration(String metadataCollectionId);
+
+
+ /**
+ * Remove details of the requested remote repository's registration from the store.
+ *
+ * @param metadataCollectionId - unique identifier for the repository's metadata collection
+ */
+ void removeRemoteRegistration(String metadataCollectionId);
+
+
+ /**
+ * Remove the local and remote registrations from the cohort registry store since the local server has
+ * unregistered from the cohort.
+ */
+ void clearAllRegistrations();
+
+
+ /**
+ * Flush all changes and close the registry store.
+ */
+ void close();
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/8a57e657/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStoreConnectorBase.java
----------------------------------------------------------------------
diff --git a/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStoreConnectorBase.java b/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStoreConnectorBase.java
new file mode 100644
index 0000000..dbd7b28
--- /dev/null
+++ b/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStoreConnectorBase.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.omrs.metadatahighway.cohortregistry.store;
+
+import org.apache.atlas.ocf.ConnectorBase;
+
+public abstract class OMRSCohortRegistryStoreConnectorBase extends ConnectorBase implements OMRSCohortRegistryStore
+{
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/8a57e657/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStoreProviderBase.java
----------------------------------------------------------------------
diff --git a/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStoreProviderBase.java b/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStoreProviderBase.java
new file mode 100644
index 0000000..176760c
--- /dev/null
+++ b/omrs/src/main/java/org/apache/atlas/omrs/metadatahighway/cohortregistry/store/OMRSCohortRegistryStoreProviderBase.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.omrs.metadatahighway.cohortregistry.store;
+
+import org.apache.atlas.ocf.ConnectorProviderBase;
+
+/**
+ * The OMRSCohortRegistryStoreProviderBase provides a base class for the connector provider supporting OMRS
+ * cluster registry stores. It extends ConnectorProviderBase which does the creation of connector instances.
+ * The subclasses of OMRSCohortRegistryStoreProviderBase must initialize ConnectorProviderBase with the Java class
+ * name of the registry store connector implementation (by calling super.setConnectorClassName(className)).
+ * Then the connector provider will work.
+ */
+public abstract class OMRSCohortRegistryStoreProviderBase extends ConnectorProviderBase
+{
+ /**
+ * Default Constructor
+ */
+ public OMRSCohortRegistryStoreProviderBase()
+ {
+ /*
+ * Nothing to do
+ */
+ }
+}
+