You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ya...@apache.org on 2025/12/15 10:25:54 UTC

(airavata) 05/07: move thrift api into its own module

This is an automated email from the ASF dual-hosted git repository.

yasith pushed a commit to branch service-layer-improvements
in repository https://gitbox.apache.org/repos/asf/airavata.git

commit d795aefa29d4d7cfe6a801ecd2ed9a7427fe4474
Author: yasithdev <ya...@icloud.com>
AuthorDate: Sun Dec 14 16:29:29 2025 -0600

    move thrift api into its own module
---
 ...message_extends_messagingevent_b2e95031.plan.md | 133 ++++
 ...dependencies_from_airavata-api_bf447176.plan.md | 158 +++++
 .../thrift_decoupling_refactoring_244a37ca.plan.md | 422 ++++++++++++
 airavata-api/pom.xml                               |  74 +-
 .../org/apache/airavata/AiravataApplication.java   |   6 +-
 .../accountprovisioning/SSHAccountManager.java     |   4 +-
 .../airavata/api/thrift/util/ThriftUtils.java      |  75 --
 .../common/exception/AiravataClientException.java  |  65 ++
 .../common/exception/AiravataErrorType.java        |  67 ++
 .../common/exception/AiravataSystemException.java  |  55 ++
 .../exception/AuthenticationException.java}        |  42 +-
 .../exception/AuthorizationException.java}         |  42 +-
 .../exception/DuplicateEntryException.java}        |  42 +-
 .../common/exception/ExceptionHandlerUtil.java     |  19 +-
 .../exception/ExperimentNotFoundException.java}    |  42 +-
 .../exception/InvalidRequestException.java}        |  42 +-
 .../exception/LaunchValidationException.java       |  65 ++
 .../exception/ProjectNotFoundException.java}       |  43 +-
 .../exception/TimedOutException.java}              |  24 +-
 .../common/exception/ValidationResults.java        |  66 ++
 .../airavata/common/exception/ValidatorResult.java |  65 ++
 .../model/AiravataCommonsConstants.java}           |  16 +-
 .../airavata/common/model/AiravataWorkflow.java    | 161 +++++
 .../model/ApplicationDeploymentDescription.java    | 242 +++++++
 .../model/ApplicationInterfaceDescription.java     | 151 ++++
 .../airavata/common/model/ApplicationModule.java   |  88 +++
 .../common/model/ApplicationParallelismType.java   |  61 ++
 .../airavata/common/model/ApplicationState.java    |  70 ++
 .../airavata/common/model/ApplicationStatus.java   |  88 +++
 .../common/model/AwsComputeResourcePreference.java |  80 +++
 .../apache/airavata/common/model/BatchQueue.java   | 194 ++++++
 .../common/model/BatchQueueResourcePolicy.java     | 127 ++++
 .../airavata/common/model/CloudJobSubmission.java  | 110 +++
 .../airavata/common/model/CommandObject.java       |  66 ++
 .../airavata/common/model/ComponentState.java      |  64 ++
 .../airavata/common/model/ComponentStatus.java     |  78 +++
 .../airavata/common/model/ComponentType.java}      |  33 +-
 .../ComputationalResourceSchedulingModel.java      | 196 ++++++
 .../common/model/ComputeResourceDescription.java   | 254 +++++++
 .../model/ComputeResourcePolicy.java}              |  67 +-
 .../common/model/ComputeResourcePreference.java    | 244 +++++++
 .../common/model/ComputeResourceReservation.java   | 108 +++
 .../common/model/ComputeResourceType.java}         |  33 +-
 .../apache/airavata/common/model/CrudType.java}    |  36 +-
 .../airavata/common/model/CustomDashboard.java     | 330 +++++++++
 .../airavata/common/model/DBEventMessage.java      |  94 +++
 .../common/model/DBEventMessageContext.java        | 101 +++
 .../airavata/common/model/DBEventPublisher.java    |  57 ++
 .../common/model/DBEventPublisherContext.java      |  79 +++
 .../airavata/common/model/DBEventSubscriber.java   |  57 ++
 .../apache/airavata/common/model/DBEventType.java} |  33 +-
 .../org/apache/airavata/common/model/DMType.java}  |  33 +-
 .../apache/airavata/common/model/DataBlock.java    |  98 +++
 .../common/model/DataMovementInterface.java        | 116 ++++
 .../model/DataMovementProtocol.java}               |  52 +-
 .../airavata/common/model/DataProductModel.java    | 193 ++++++
 .../airavata/common/model/DataProductType.java}    |  33 +-
 .../model/DataReplicaLocationModel.java}           | 175 +++--
 .../model/DataStageType.java}                      |  43 +-
 .../common/model/DataStagingTaskModel.java         | 138 ++++
 .../org/apache/airavata/common/model/DataType.java |  64 ++
 .../apache/airavata/common/model/EdgeModel.java    |  88 +++
 .../apache/airavata/common/model/EntityType.java   |  67 ++
 .../common/model/EnvironmentSetupTaskModel.java    |  66 ++
 .../model/EnvironmentSpecificPreferences.java      | 101 +++
 .../apache/airavata/common/model/ErrorModel.java   | 116 ++++
 .../model/ExperimentCleanupStrategy.java}          |  49 +-
 .../model/ExperimentIntermediateOutputsEvent.java  |  85 +++
 .../airavata/common/model/ExperimentModel.java     | 287 ++++++++
 .../common/model/ExperimentSearchFields.java       |  70 ++
 .../airavata/common/model/ExperimentState.java     |  70 ++
 .../common/model/ExperimentStatistics.java         | 186 +++++
 .../airavata/common/model/ExperimentStatus.java    |  88 +++
 .../common/model/ExperimentStatusChangeEvent.java  |  78 +++
 .../common/model/ExperimentSubmitEvent.java        |  71 ++
 .../common/model/ExperimentSummaryModel.java       | 171 +++++
 .../airavata/common/model/ExperimentType.java}     |  33 +-
 .../model/FileSystems.java}                        |  52 +-
 .../org/apache/airavata/common/model/Gateway.java  | 276 ++++++++
 .../common/model/GatewayApprovalStatus.java        |  67 ++
 .../airavata/common/model/GatewayGroups.java       |  89 +++
 .../common/model/GatewayResourceProfile.java       | 117 ++++
 .../common/model/GatewayUsageReportingCommand.java |  78 +++
 .../airavata/common/model/GlobusJobSubmission.java |  79 +++
 .../airavata/common/model/GridFTPDataMovement.java |  79 +++
 .../org/apache/airavata/common/model/Group.java    |  66 ++
 .../model/GroupAccountSSHProvisionerConfig.java    |  88 +++
 .../model/GroupComputeResourcePreference.java      | 163 +++++
 .../apache/airavata/common/model/GroupModel.java   | 109 +++
 .../common/model/GroupResourceProfile.java         | 151 ++++
 .../apache/airavata/common/model/HandlerState.java |  70 ++
 .../airavata/common/model/HandlerStatus.java       |  88 +++
 .../apache/airavata/common/model/HandlerType.java} |  33 +-
 .../model/IOType.java}                             |  33 +-
 .../airavata/common/model/InputDataObjectType.java | 206 ++++++
 .../airavata/common/model/JobIdentifier.java       | 106 +++
 .../airavata/common/model/JobManagerCommand.java   |  73 ++
 .../org/apache/airavata/common/model/JobModel.java | 183 +++++
 .../org/apache/airavata/common/model/JobState.java |  70 ++
 .../apache/airavata/common/model/JobStatus.java    |  92 +++
 .../common/model/JobStatusChangeEvent.java         |  69 ++
 .../common/model/JobStatusChangeRequestEvent.java  |  66 ++
 .../common/model/JobSubmissionInterface.java       |  78 +++
 .../common/model/JobSubmissionProtocol.java        |  64 ++
 .../common/model/JobSubmissionTaskModel.java       |  78 +++
 .../airavata/common/model/LOCALDataMovement.java   |  57 ++
 .../airavata/common/model/LOCALSubmission.java     |  78 +++
 .../org/apache/airavata/common/model/Message.java  |  99 +++
 .../model/MessageLevel.java}                       |  46 +-
 .../apache/airavata/common/model/MessageType.java  |  73 ++
 .../model/MessagingEvent.java}                     |   8 +-
 .../apache/airavata/common/model/MonitorMode.java  |  61 ++
 .../airavata/common/model/MonitorTaskModel.java    |  57 ++
 .../airavata/common/model/NSFDemographics.java     | 110 +++
 .../apache/airavata/common/model/NodeModel.java    | 108 +++
 .../apache/airavata/common/model/Notification.java | 137 ++++
 .../model/NotificationPriority.java}               |  43 +-
 .../common/model/OutputDataObjectType.java         | 183 +++++
 .../org/apache/airavata/common/model/Parser.java   | 131 ++++
 .../airavata/common/model/ParserConnector.java     | 100 +++
 .../common/model/ParserConnectorInput.java         |  98 +++
 .../model/ParserInput.java}                        |  73 +-
 .../model/ParserOutput.java}                       |  73 +-
 .../airavata/common/model/ParsingTemplate.java     |  99 +++
 .../model/ParsingTemplateInput.java}               |  69 +-
 .../apache/airavata/common/model/PortModel.java    |  98 +++
 .../airavata/common/model/ProcessIdentifier.java   |  84 +++
 .../apache/airavata/common/model/ProcessModel.java | 357 ++++++++++
 .../apache/airavata/common/model/ProcessState.java |  94 +++
 .../airavata/common/model/ProcessStatus.java       | 102 +++
 .../common/model/ProcessStatusChangeEvent.java     |  71 ++
 .../model/ProcessStatusChangeRequestEvent.java     |  66 ++
 .../airavata/common/model/ProcessSubmitEvent.java  |  95 +++
 .../common/model/ProcessTerminateEvent.java        |  94 +++
 .../airavata/common/model/ProcessWorkflow.java     |  88 +++
 .../org/apache/airavata/common/model/Project.java  | 130 ++++
 .../model/ProjectSearchFields.java}                |  40 +-
 .../model/ProviderName.java}                       |  43 +-
 .../airavata/common/model/QueueStatusModel.java    | 117 ++++
 .../model/ReplicaLocationCategory.java}            |  49 +-
 .../common/model/ReplicaPersistentType.java}       |  33 +-
 .../airavata/common/model/ResourceJobManager.java  | 120 ++++
 .../common/model/ResourceJobManagerType.java       |  67 ++
 .../model/ResourcePermissionType.java}             |  49 +-
 .../airavata/common/model/SCPDataMovement.java     |  89 +++
 .../model/SSHAccountProvisionerConfigParam.java    |  88 +++
 .../SSHAccountProvisionerConfigParamType.java}     |  43 +-
 .../model/SSHAccountProvisionerDescription.java    |  89 +++
 .../airavata/common/model/SSHJobSubmission.java    | 128 ++++
 .../airavata/common/model/SecurityProtocol.java    |  61 ++
 .../apache/airavata/common/model/SetEnvPaths.java  |  77 +++
 .../airavata/common/model/SharingResourceType.java |  64 ++
 .../model/SlurmComputeResourcePreference.java      | 142 ++++
 .../org/apache/airavata/common/model/Status.java   |  85 +++
 .../common/model/StorageDirectoryInfo.java         |  66 ++
 .../airavata/common/model/StoragePreference.java   |  90 +++
 .../common/model/StorageResourceDescription.java   | 128 ++++
 .../airavata/common/model/StorageVolumeInfo.java   | 149 ++++
 .../airavata/common/model/TaskIdentifier.java      |  95 +++
 .../apache/airavata/common/model/TaskModel.java    | 183 +++++
 .../common/model/TaskOutputChangeEvent.java        |  67 ++
 .../model/TaskState.java}                          |  52 +-
 .../apache/airavata/common/model/TaskStatus.java   |  88 +++
 .../common/model/TaskStatusChangeEvent.java        |  71 ++
 .../common/model/TaskStatusChangeRequestEvent.java |  66 ++
 .../apache/airavata/common/model/TaskTypes.java    |  61 ++
 .../org/apache/airavata/common/model/Tenant.java   | 183 +++++
 .../common/model/TenantApprovalStatus.java         |  67 ++
 .../apache/airavata/common/model/TenantConfig.java |  89 +++
 .../airavata/common/model/TenantPreferences.java   |  78 +++
 .../airavata/common/model/TenantProfile.java       |  80 +++
 .../model/USCitizenship.java}                      |  46 +-
 .../airavata/common/model/UnicoreDataMovement.java |  78 +++
 .../common/model/UnicoreJobSubmission.java         |  78 +++
 .../org/apache/airavata/common/model/User.java     | 108 +++
 .../model/UserComputeResourcePreference.java       | 183 +++++
 .../common/model/UserConfigurationDataModel.java   | 201 ++++++
 .../apache/airavata/common/model/UserProfile.java  | 342 +++++++++
 .../airavata/common/model/UserResourceProfile.java | 128 ++++
 .../common/model/UserStoragePreference.java        |  90 +++
 .../airavata/common/model/ValidationResults.java   |  69 ++
 .../airavata/common/model/ValidatorResult.java     |  66 ++
 .../airavata/common/model/WorkflowApplication.java | 195 ++++++
 .../airavata/common/model/WorkflowConnection.java  | 150 ++++
 .../common/model/WorkflowExecutionState.java       |  79 +++
 .../airavata/common/model/WorkflowHandler.java     | 130 ++++
 .../airavata/common/model/WorkflowModel.java       | 142 ++++
 .../common/model/WorkflowRuntimeState.java         |  64 ++
 .../airavata/common/model/WorkflowStatus.java      |  88 +++
 .../model/disability.java}                         |  49 +-
 .../apache/airavata/common/model/ethnicity.java}   |  33 +-
 .../org/apache/airavata/common/model/race.java     |  58 ++
 .../org/apache/airavata/common/utils/JPAUtils.java |   5 +
 .../apache/airavata/config/DozerMapperConfig.java  |  12 +-
 .../airavata/config/SecurityManagerConfig.java     |   2 +-
 .../exception/CredentialStoreException.java}       |  44 +-
 .../credential/model/CertificateCredential.java    | 135 ++++
 .../airavata/credential/model/CommunityUser.java   |  86 +++
 .../credential/model/CredentialSummary.java        | 124 ++++
 .../credential/model/PasswordCredential.java       | 124 ++++
 .../airavata/credential/model/SSHCredential.java   | 135 ++++
 .../model/SummaryType.java}                        |  14 +-
 .../airavata/helix/impl/task/AiravataTask.java     |  44 +-
 .../airavata/helix/impl/task/TaskContext.java      |  21 +-
 .../helix/impl/task/aws/AWSJobSubmissionTask.java  |  18 +-
 .../helix/impl/task/parsing/DataParsingTask.java   |  11 +-
 .../impl/task/staging/InputDataStagingTask.java    |   2 +-
 .../impl/task/staging/OutputDataStagingTask.java   |   9 +-
 .../task/submission/DefaultJobSubmissionTask.java  |  11 +-
 .../task/submission/config/GroovyMapBuilder.java   |  10 +-
 .../config/app/parser/HTCondorOutputParser.java    |  16 +-
 .../config/app/parser/LSFOutputParser.java         |   8 +-
 .../config/app/parser/PBSOutputParser.java         |  13 +-
 .../config/app/parser/SlurmOutputParser.java       |  12 +-
 .../config/app/parser/UGEOutputParser.java         |  12 +-
 .../helix/impl/workflow/PostWorkflowManager.java   |   4 +-
 .../helix/impl/workflow/PreWorkflowManager.java    |  19 +-
 .../messaging/impl/DBEventMessageHandler.java      |  10 +-
 .../airavata/messaging/core/MessageContext.java    |  11 +-
 .../airavata/messaging/core/MessageWrapper.java    | 139 ++++
 .../messaging/core/impl/ExperimentConsumer.java    |  63 +-
 .../messaging/core/impl/MessageConsumer.java       |  20 +-
 .../messaging/core/impl/ProcessConsumer.java       |  61 +-
 .../messaging/core/impl/RabbitMQPublisher.java     |  31 +-
 .../messaging/core/impl/StatusConsumer.java        |  91 +--
 .../messaging/core/util/DBEventPublisherUtils.java |  58 +-
 .../DefaultComputeResourceSelectionPolicy.java     |   2 +-
 .../selection/MultipleComputeResourcePolicy.java   |   2 +-
 .../monitor/compute/job/MonitoringJob.java         |   2 +-
 .../orchestrator/impl/SimpleOrchestratorImpl.java  |  49 +-
 .../orchestrator/job/GFACPassiveJobSubmitter.java  |   3 +-
 .../orchestrator/utils/OrchestratorUtils.java      |   4 +-
 .../validation/impl/ValidationServiceImpl.java     |   8 +-
 .../validator/BatchQueueValidator.java             |   4 +-
 .../validator/GroupResourceProfileValidator.java   |   2 +-
 .../exception/GroupManagerServiceException.java}   |  43 +-
 .../exception/IamAdminServicesException.java}      |  43 +-
 .../exception/TenantProfileServiceException.java}  |  43 +-
 .../exception/UserProfileServiceException.java}    |  43 +-
 .../airavata/profile/utils/QueryConstants.java     |  52 --
 .../WorkflowConnectionEntity.java                  |   2 +-
 .../WorkflowDataBlockEntity.java                   |   2 +-
 .../entities/appcatalog/AppEnvironmentEntity.java  |   2 +-
 .../appcatalog/BatchQueueResourcePolicyEntity.java |   4 +-
 .../appcatalog/ComputeResourcePolicyEntity.java    |   4 +-
 .../entities/appcatalog/LocalSubmissionEntity.java |   2 +-
 .../entities/appcatalog/ParserConnectorEntity.java |   6 +-
 .../appcatalog/ParserConnectorInputEntity.java     |   6 +-
 .../entities/appcatalog/ParserInputEntity.java     |   2 +-
 .../entities/appcatalog/ParserOutputEntity.java    |   2 +-
 .../appcatalog/ParsingTemplateInputEntity.java     |   4 +-
 .../entities/expcatalog/ProcessEntity.java         |   2 +-
 .../registry/entities/expcatalog/TaskEntity.java   |   2 +-
 .../replicacatalog/DataReplicaLocationEntity.java  |   2 +-
 .../exception/RegistryServiceException.java}       |  44 +-
 .../messaging/RegistryServiceDBEventHandler.java   | 178 +++--
 .../RegistryServiceDBEventMessagingFactory.java    |   9 +-
 .../model/RegistryApiConstants.java}               |  16 +-
 .../repositories/expcatalog/UserRepository.java    |   3 +-
 .../services/ApplicationDeploymentService.java     |   4 +-
 .../services/ApplicationInterfaceService.java      |   6 +-
 .../registry/services/ComputeResourceService.java  |   6 +-
 .../registry/services/ExperimentService.java       |   5 +-
 .../services/GroupResourceProfileService.java      |  18 +-
 .../airavata/registry/services/JobService.java     |   4 +-
 .../airavata/registry/services/ProcessService.java |   9 +-
 .../registry/services/StorageResourceService.java  |   4 +-
 .../airavata/registry/services/TaskService.java    |   4 +-
 .../airavata/registry/utils/CustomBeanFactory.java |  69 +-
 .../airavata/registry/utils/QueryConstants.java    | 293 --------
 .../airavata/security/KeyCloakSecurityManager.java |   6 +-
 .../apache/airavata/security/model/AuthzToken.java |  84 +++
 .../apache/airavata/service/AiravataService.java   |  55 +-
 .../airavata/service/SharingRegistryService.java   |  11 +-
 .../experiment/impl/ExperimentServiceImpl.java     |   7 +-
 .../service/orchestrator/OrchestratorService.java  | 107 ++-
 .../service/profile/TenantProfileService.java      |   5 +-
 .../service/profile/UserProfileService.java        |   2 +-
 .../airavata/service/registry/RegistryService.java |  28 +-
 .../service/security/GroupManagerService.java      |   4 +-
 .../security/impl/AuthorizationServiceImpl.java    |   4 +-
 .../messaging/SharingServiceDBEventHandler.java    |  81 +--
 .../SharingServiceDBEventMessagingFactory.java     |   9 +-
 .../org/apache/airavata/sharing/model/Domain.java  | 113 +++
 .../model/DuplicateEntryException.java}            |  43 +-
 .../org/apache/airavata/sharing/model/Entity.java  | 203 ++++++
 .../model/EntitySearchField.java}                  |  20 +-
 .../apache/airavata/sharing/model/EntityType.java  | 113 +++
 .../apache/airavata/sharing/model/GroupAdmin.java  |  77 +++
 .../model/GroupCardinality.java}                   |  12 +-
 .../model/GroupChildType.java}                     |  12 +-
 .../airavata/sharing/model/GroupMembership.java    | 113 +++
 .../model/GroupType.java}                          |  12 +-
 .../airavata/sharing/model/PermissionType.java     | 113 +++
 .../model/SearchCondition.java}                    |  16 +-
 .../airavata/sharing/model/SearchCriteria.java     |  80 +++
 .../org/apache/airavata/sharing/model/Sharing.java | 143 ++++
 .../model/SharingRegistryException.java}           |  43 +-
 .../model/SharingType.java}                        |  13 +-
 .../org/apache/airavata/sharing/model/User.java    | 146 ++++
 .../apache/airavata/sharing/model/UserGroup.java   | 168 +++++
 .../sharing/services/PermissionTypeService.java    |   9 +-
 .../apache/airavata/util/ExperimentModelUtil.java  |   6 +-
 .../util/GroupComputeResourcePreferenceUtil.java   |   4 +-
 .../SSHAccountProvisionerFactoryTest.java          |   5 +-
 .../airavata/accountprovisioning/SSHUtilTest.java  |   5 +-
 .../server/TestOrchestratorServiceServer.java      | 133 ----
 .../thrift/server/TestSharingRegistryServer.java   | 415 -----------
 .../common/utils/ApplicationSettingsTest.java      |   5 +-
 .../airavata/common/utils/NameValidatorTest.java   |   5 +-
 .../airavata/common/utils/SecurityUtilTest.java    |  17 +-
 .../apache/airavata/config/EntityLoadingTest.java  |  60 +-
 .../config/PersistenceConfigurationTest.java       |  58 +-
 .../airavata/config/SpringContextLoadTest.java     | 131 ++--
 .../credential/impl/ssh/SSHSummaryTest.java        |  32 +-
 .../credential/impl/store/SSHCredentialTest.java   |  27 +-
 .../credential/utils/TokenGeneratorTest.java       |  29 -
 .../apache/airavata/messaging/core/TestClient.java |   6 +-
 .../orchestrator/core/BaseOrchestratorTest.java    |   5 +-
 .../orchestrator/core/NewOrchestratorTest.java     |   5 +-
 .../repositories/WorkspaceRepositoryTest.java      |   6 +-
 .../ApplicationDeploymentRepositoryTest.java       |  12 +-
 .../ApplicationInterfaceRepositoryTest.java        |  22 +-
 .../appcatalog/ComputeResourceRepositoryTest.java  |   6 +-
 .../appcatalog/GatewayGroupsRepositoryTest.java    |   6 +-
 .../appcatalog/GatewayProfileRepositoryTest.java   |  10 +-
 .../GroupResourceProfileRepositoryTest.java        |  51 +-
 .../JobSubmissionInterfaceRepositoryTest.java      |  14 +-
 .../appcatalog/StorageResourceRepositoryTest.java  |   6 +-
 .../UserResourceProfileRepositoryTest.java         |   6 +-
 .../expcatalog/ExperimentErrorRepositoryTest.java  |   6 +-
 .../expcatalog/ExperimentInputRepositoryTest.java  |   6 +-
 .../expcatalog/ExperimentOutputRepositoryTest.java |   6 +-
 .../expcatalog/ExperimentRepositoryTest.java       |  47 +-
 .../expcatalog/ExperimentStatusRepositoryTest.java |  12 +-
 .../ExperimentSummaryRepositoryTest.java           |  19 +-
 .../expcatalog/GatewayRepositoryTest.java          |   6 +-
 .../repositories/expcatalog/JobRepositoryTest.java |  13 +-
 .../expcatalog/JobStatusRepositoryTest.java        |   9 +-
 .../expcatalog/NotificationRepositoryTest.java     |   6 +-
 .../expcatalog/ProcessErrorRepositoryTest.java     |   9 +-
 .../expcatalog/ProcessInputRepositoryTest.java     |   9 +-
 .../expcatalog/ProcessOutputRepositoryTest.java    |   9 +-
 .../expcatalog/ProcessRepositoryTest.java          |  35 +-
 .../expcatalog/ProcessStatusRepositoryTest.java    |   9 +-
 .../expcatalog/ProjectRepositoryTest.java          |  12 +-
 .../expcatalog/QueueStatusRepositoryTest.java      |   6 +-
 .../expcatalog/TaskErrorRepositoryTest.java        |   9 +-
 .../expcatalog/TaskRepositoryTest.java             |  19 +-
 .../expcatalog/TaskStatusRepositoryTest.java       |  12 +-
 .../expcatalog/UserRepositoryTest.java             |   6 +-
 .../replicacatalog/DataProductRepositoryTest.java  |  10 +-
 .../DataReplicaLocationRepositoryTest.java         |   6 +-
 .../workflowcatalog/WorkflowRepositoryTest.java    |  26 +-
 .../registry/utils/CustomBeanFactoryTest.java      |  88 ++-
 .../security/GatewayGroupsInitializerTest.java     |  30 +-
 .../security/KeyCloakSecurityManagerTest.java      |  36 +-
 .../AuthenticatorConfigurationReaderTest.java      |  17 +-
 .../AwsComputeResourceIntegrationTest.java         |   2 +-
 .../OrchestratorServiceIntegrationTest.java        | 125 +++-
 .../integration/ServiceIntegrationTestBase.java    |  19 +-
 .../SharingRegistryServiceIntegrationTest.java     | 531 +++++++++-----
 .../SlurmComputeResourceIntegrationTest.java       |   4 +-
 .../service/integration/TestDataFactory.java       |   2 +-
 .../UserProfileServiceIntegrationTest.java         |   6 +-
 .../GroupComputeResourcePreferenceUtilTest.java    |  77 ++-
 .../src/test/resources/airavata.properties         |  12 +-
 modules/thrift-api/pom.xml                         | 150 ++++
 .../client/AiravataServiceClientFactory.java       |   4 +-
 .../client/CredentialServiceClientFactory.java     |   4 +-
 .../client/OrchestratorServiceClientFactory.java   |   4 +-
 .../client/ProfileServiceClientFactory.java        |  26 +-
 .../client/RegistryServiceClientFactory.java       |   6 +-
 .../SharingRegistryServiceClientFactory.java       |   6 +-
 .../thriftapi}/handler/AiravataServiceHandler.java | 766 +++++++++++++++------
 .../handler/CredentialServiceHandler.java          |   2 +-
 .../handler/GroupManagerServiceHandler.java        |   2 +-
 .../thriftapi}/handler/IamAdminServiceHandler.java |   2 +-
 .../handler/OrchestratorServiceHandler.java        |   2 +-
 .../thriftapi}/handler/RegistryServiceHandler.java |   2 +-
 .../handler/SharingRegistryServerHandler.java      |   2 +-
 .../handler/TenantProfileServiceHandler.java       |   2 +-
 .../handler/UserProfileServiceHandler.java         |   2 +-
 .../thriftapi/mapper/AiravataWorkflowMapper.java   |  34 +-
 .../ApplicationDeploymentDescriptionMapper.java    |  46 ++
 .../ApplicationInterfaceDescriptionMapper.java     |  46 ++
 .../thriftapi/mapper/ApplicationModuleMapper.java  |  34 +-
 .../thriftapi/mapper/ApplicationStatusMapper.java  |  34 +-
 .../thriftapi/mapper/AuthzTokenMapper.java         |  33 +-
 .../mapper/AwsComputeResourcePreferenceMapper.java |  44 ++
 .../thriftapi/mapper/BatchQueueMapper.java         |  34 +-
 .../mapper/BatchQueueResourcePolicyMapper.java     |  44 ++
 .../mapper/CertificateCredentialMapper.java        |  33 +-
 .../thriftapi/mapper/CloudJobSubmissionMapper.java |  34 +-
 .../thriftapi/mapper/CommandObjectMapper.java      |  34 +-
 .../thriftapi/mapper/CommunityUserMapper.java      |  33 +-
 .../thriftapi/mapper/ComponentStatusMapper.java    |  34 +-
 ...ComputationalResourceSchedulingModelMapper.java |  47 ++
 .../mapper/ComputeResourceDescriptionMapper.java   |  44 ++
 .../mapper/ComputeResourcePolicyMapper.java        |  44 ++
 .../mapper/ComputeResourcePreferenceMapper.java    |  44 ++
 .../mapper/ComputeResourceReservationMapper.java   |  44 ++
 .../mapper/CredentialStoreExceptionMapper.java     |  45 ++
 .../thriftapi/mapper/CredentialSummaryMapper.java  |  33 +-
 .../thriftapi/mapper/CustomDashboardMapper.java    |  34 +-
 .../thriftapi/mapper/DBEventMessageMapper.java     |  34 +-
 .../mapper/DBEventPublisherContextMapper.java      |  44 ++
 .../thriftapi/mapper/DBEventPublisherMapper.java   |  34 +-
 .../thriftapi/mapper/DBEventSubscriberMapper.java  |  34 +-
 .../airavata/thriftapi/mapper/DataBlockMapper.java |  34 +-
 .../mapper/DataMovementInterfaceMapper.java        |  44 ++
 .../thriftapi/mapper/DataProductModelMapper.java   |  34 +-
 .../mapper/DataReplicaLocationModelMapper.java     |  44 ++
 .../mapper/DataStagingTaskModelMapper.java         |  34 +-
 .../airavata/thriftapi/mapper/EdgeModelMapper.java |  34 +-
 .../mapper/EnvironmentSetupTaskModelMapper.java    |  44 ++
 .../thriftapi/mapper/ErrorModelMapper.java         |  34 +-
 .../ExperimentIntermediateOutputsEventMapper.java  |  47 ++
 .../thriftapi/mapper/ExperimentModelMapper.java    |  34 +-
 .../mapper/ExperimentStatisticsMapper.java         |  34 +-
 .../mapper/ExperimentStatusChangeEventMapper.java  |  44 ++
 .../thriftapi/mapper/ExperimentStatusMapper.java   |  34 +-
 .../mapper/ExperimentSubmitEventMapper.java        |  44 ++
 .../mapper/ExperimentSummaryModelMapper.java       |  44 ++
 .../thriftapi/mapper/GatewayGroupsMapper.java      |  34 +-
 .../airavata/thriftapi/mapper/GatewayMapper.java   |  34 +-
 .../mapper/GatewayResourceProfileMapper.java       |  44 ++
 .../mapper/GatewayUsageReportingCommandMapper.java |  44 ++
 .../mapper/GlobusJobSubmissionMapper.java          |  34 +-
 .../mapper/GridFTPDataMovementMapper.java          |  34 +-
 .../GroupAccountSSHProvisionerConfigMapper.java    |  46 ++
 .../GroupComputeResourcePreferenceMapper.java      |  44 ++
 .../airavata/thriftapi/mapper/GroupMapper.java     |  34 +-
 .../thriftapi/mapper/GroupModelMapper.java         |  34 +-
 .../mapper/GroupResourceProfileMapper.java         |  34 +-
 .../thriftapi/mapper/HandlerStatusMapper.java      |  34 +-
 .../mapper/InputDataObjectTypeMapper.java          |  34 +-
 .../thriftapi/mapper/JobIdentifierMapper.java      |  34 +-
 .../airavata/thriftapi/mapper/JobModelMapper.java  |  34 +-
 .../mapper/JobStatusChangeEventMapper.java         |  34 +-
 .../mapper/JobStatusChangeRequestEventMapper.java  |  44 ++
 .../airavata/thriftapi/mapper/JobStatusMapper.java |  34 +-
 .../mapper/JobSubmissionInterfaceMapper.java       |  36 +-
 .../mapper/JobSubmissionTaskModelMapper.java       |  44 ++
 .../thriftapi/mapper/LOCALDataMovementMapper.java  |  34 +-
 .../thriftapi/mapper/LOCALSubmissionMapper.java    |  34 +-
 .../airavata/thriftapi/mapper/MessageMapper.java   |  34 +-
 .../airavata/thriftapi/mapper/ModelMapper.java     |  12 +-
 .../thriftapi/mapper/MonitorTaskModelMapper.java   |  34 +-
 .../thriftapi/mapper/NSFDemographicsMapper.java    |  34 +-
 .../airavata/thriftapi/mapper/NodeModelMapper.java |  34 +-
 .../thriftapi/mapper/NotificationMapper.java       |  34 +-
 .../mapper/OutputDataObjectTypeMapper.java         |  34 +-
 .../mapper/ParserConnectorInputMapper.java         |  34 +-
 .../thriftapi/mapper/ParserConnectorMapper.java    |  34 +-
 .../thriftapi/mapper/ParserInputMapper.java        |  34 +-
 .../airavata/thriftapi/mapper/ParserMapper.java    |  34 +-
 .../thriftapi/mapper/ParserOutputMapper.java       |  34 +-
 .../mapper/ParsingTemplateInputMapper.java         |  34 +-
 .../thriftapi/mapper/ParsingTemplateMapper.java    |  34 +-
 .../thriftapi/mapper/PasswordCredentialMapper.java |  33 +-
 .../airavata/thriftapi/mapper/PortModelMapper.java |  34 +-
 .../thriftapi/mapper/ProcessIdentifierMapper.java  |  34 +-
 .../thriftapi/mapper/ProcessModelMapper.java       |  34 +-
 .../mapper/ProcessStatusChangeEventMapper.java     |  44 ++
 .../ProcessStatusChangeRequestEventMapper.java     |  46 ++
 .../thriftapi/mapper/ProcessStatusMapper.java      |  34 +-
 .../thriftapi/mapper/ProcessSubmitEventMapper.java |  34 +-
 .../mapper/ProcessTerminateEventMapper.java        |  44 ++
 .../thriftapi/mapper/ProcessWorkflowMapper.java    |  34 +-
 .../airavata/thriftapi/mapper/ProjectMapper.java   |  34 +-
 .../thriftapi/mapper/QueueStatusModelMapper.java   |  34 +-
 .../mapper/RegistryServiceExceptionMapper.java     |  43 ++
 .../thriftapi/mapper/ResourceJobManagerMapper.java |  34 +-
 .../thriftapi/mapper/SCPDataMovementMapper.java    |  34 +-
 .../SSHAccountProvisionerConfigParamMapper.java    |  46 ++
 .../SSHAccountProvisionerDescriptionMapper.java    |  46 ++
 .../thriftapi/mapper/SSHCredentialMapper.java      |  33 +-
 .../thriftapi/mapper/SSHJobSubmissionMapper.java   |  34 +-
 .../thriftapi/mapper/SetEnvPathsMapper.java        |  34 +-
 .../SlurmComputeResourcePreferenceMapper.java      |  44 ++
 .../mapper/StorageDirectoryInfoMapper.java         |  34 +-
 .../thriftapi/mapper/StoragePreferenceMapper.java  |  34 +-
 .../mapper/StorageResourceDescriptionMapper.java   |  44 ++
 .../thriftapi/mapper/StorageVolumeInfoMapper.java  |  34 +-
 .../thriftapi/mapper/SummaryTypeMapper.java        |  33 +-
 .../thriftapi/mapper/TaskIdentifierMapper.java     |  34 +-
 .../airavata/thriftapi/mapper/TaskModelMapper.java |  34 +-
 .../mapper/TaskOutputChangeEventMapper.java        |  44 ++
 .../mapper/TaskStatusChangeEventMapper.java        |  44 ++
 .../mapper/TaskStatusChangeRequestEventMapper.java |  44 ++
 .../thriftapi/mapper/TaskStatusMapper.java         |  34 +-
 .../thriftapi/mapper/TenantConfigMapper.java       |  34 +-
 .../airavata/thriftapi/mapper/TenantMapper.java    |  34 +-
 .../thriftapi/mapper/TenantPreferencesMapper.java  |  34 +-
 .../mapper/UnicoreDataMovementMapper.java          |  34 +-
 .../mapper/UnicoreJobSubmissionMapper.java         |  34 +-
 .../UserComputeResourcePreferenceMapper.java       |  44 ++
 .../mapper/UserConfigurationDataModelMapper.java   |  44 ++
 .../airavata/thriftapi/mapper/UserMapper.java      |  34 +-
 .../thriftapi/mapper/UserProfileMapper.java        |  34 +-
 .../mapper/UserResourceProfileMapper.java          |  34 +-
 .../mapper/UserStoragePreferenceMapper.java        |  44 ++
 .../thriftapi/mapper/ValidationResultsMapper.java  |  34 +-
 .../thriftapi/mapper/ValidatorResultMapper.java    |  34 +-
 .../mapper/WorkflowApplicationMapper.java          |  34 +-
 .../thriftapi/mapper/WorkflowConnectionMapper.java |  34 +-
 .../thriftapi/mapper/WorkflowHandlerMapper.java    |  34 +-
 .../thriftapi/mapper/WorkflowModelMapper.java      |  34 +-
 .../thriftapi/mapper/WorkflowStatusMapper.java     |  34 +-
 .../thriftapi}/server/AiravataServiceServer.java   |   4 +-
 .../thriftapi}/server/CredentialServiceServer.java |   4 +-
 .../server/OrchestratorServiceServer.java          |   4 +-
 .../thriftapi}/server/ProfileServiceServer.java    |  10 +-
 .../thriftapi}/server/RegistryServiceServer.java   |   6 +-
 .../thriftapi}/server/SharingRegistryServer.java   |   6 +-
 .../thriftapi}/util/AiravataServiceConstants.java  |   2 +-
 .../thriftapi}/util/RegistryServiceConstants.java  |   2 +-
 .../thriftapi}/util/SharingRegistryConstants.java  |   2 +-
 .../airavata/thriftapi}/util/ThriftClientPool.java |   4 +-
 .../thriftapi}/util/ThriftDataModelConversion.java |   2 +-
 .../client/TestAiravataServiceClientFactory.java   |   4 +-
 .../client/TestOrchestratorClientFactory.java      |   2 +-
 .../airavata/thriftapi}/client/TestSSLClient.java  |   2 +-
 .../handler/TestSharingRegistryHandler.java        |  10 +-
 .../server/TestAiravataServiceServer.java          |   2 +-
 .../server/TestCredentialServiceServer.java        |   2 +-
 .../server/TestProfileServiceServer.java           |   2 +-
 .../server/TestRegistryServiceServer.java          |   2 +-
 .../thriftapi}/util/ThriftClientPoolTest.java      |   4 +-
 pom.xml                                            |   7 +
 .../airavata-apis/airavata_api.thrift              |   2 +-
 .../airavata-apis/airavata_commons.thrift          |   2 +-
 .../airavata-apis/airavata_errors.thrift           |   2 +-
 .../airavata-apis/db_event_model.thrift            |   2 +-
 .../airavata-apis/messaging_events.thrift          |   2 +-
 .../airavata-apis/security_model.thrift            |   2 +-
 .../airavata-apis/workflow_api.thrift              |   2 +-
 .../base-api/base_api.thrift                       |   2 +-
 .../data-models/account_provisioning_model.thrift  |   2 +-
 .../application_deployment_model.thrift            |   2 +-
 .../data-models/application_interface_model.thrift |   2 +-
 .../data-models/application_io_models.thrift       |   2 +-
 .../data-models/compute_resource_model.thrift      |   2 +-
 .../data-models/credential_store_models.thrift     |   2 +-
 .../data-models/data_movement_models.thrift        |   2 +-
 .../data-models/experiment_model.thrift            |   2 +-
 .../data-models/gateway_groups_model.thrift        |   2 +-
 .../gateway_resource_profile_model.thrift          |   2 +-
 .../data-models/group_manager_model.thrift         |   2 +-
 .../group_resource_profile_model.thrift            |   2 +-
 .../data-models/job_model.thrift                   |   2 +-
 .../data-models/parallelism_model.thrift           |   2 +-
 .../data-models/parser_model.thrift                |   2 +-
 .../data-models/process_model.thrift               |   2 +-
 .../data-models/replica_catalog_models.thrift      |   2 +-
 .../data-models/scheduling_model.thrift            |   2 +-
 .../data-models/sharing_models.thrift              |   2 +-
 .../data-models/status_models.thrift               |   2 +-
 .../data-models/storage_resource_model.thrift      |   2 +-
 .../data-models/task_model.thrift                  |   2 +-
 .../data-models/tenant_profile_model.thrift        |   2 +-
 .../data-models/user_profile_model.thrift          |   2 +-
 .../data-models/user_resource_profile_model.thrift |   2 +-
 .../data-models/workflow_data_model.thrift         |   2 +-
 .../data-models/workflow_model.thrift              |   2 +-
 .../data-models/workspace_model.thrift             |   2 +-
 .../service-cpis/credential-store-cpi.thrift       |   2 +-
 .../service-cpis/credential_store_errors.thrift    |   2 +-
 .../service-cpis/orchestrator-cpi.thrift           |   2 +-
 .../group-manager/group-manager-cpi.thrift         |   2 +-
 .../group-manager/group_manager_cpi_errors.thrift  |   2 +-
 .../iam-admin-services-cpi.thrift                  |   2 +-
 .../iam_admin_services_cpi_errors.thrift           |   2 +-
 .../profile-tenant/profile-tenant-cpi.thrift       |   2 +-
 .../profile_tenant_cpi_errors.thrift               |   2 +-
 .../profile-user/profile-user-cpi.thrift           |   2 +-
 .../profile-user/profile_user_cpi_errors.thrift    |   2 +-
 .../service-cpis/registry-api.thrift               |   2 +-
 .../service-cpis/registry_api_errors.thrift        |   2 +-
 .../service-cpis/sharing_cpi.thrift                |   2 +-
 .../service-cpis/user-profile-cpi.thrift           |   2 +-
 .../service-cpis/user_profile_cpi_errors.thrift    |   2 +-
 583 files changed, 25925 insertions(+), 5036 deletions(-)

diff --git a/.cursor/plans/dbeventmessage_extends_messagingevent_b2e95031.plan.md b/.cursor/plans/dbeventmessage_extends_messagingevent_b2e95031.plan.md
new file mode 100644
index 0000000000..15d0c9d080
--- /dev/null
+++ b/.cursor/plans/dbeventmessage_extends_messagingevent_b2e95031.plan.md
@@ -0,0 +1,133 @@
+---
+name: DBEventMessage extends MessagingEvent
+overview: Make DBEventMessage extend MessagingEvent to resolve the type clash with MessageContext, and fix related conversion issues in handlers and consumers.
+todos:
+  - id: extend-dbevent
+    content: Make DBEventMessage extend MessagingEvent in DBEventMessage.java
+    status: completed
+  - id: add-constructor
+    content: Add constructor DBEventMessage(MessageContext) to extract event from MessageContext
+    status: completed
+    dependencies:
+      - extend-dbevent
+  - id: fix-message-consumer
+    content: Fix MessageConsumer to properly handle DBEventMessage deserialization (may need Thrift model first, then mapper)
+    status: completed
+    dependencies:
+      - extend-dbevent
+  - id: update-handlers
+    content: Update SharingServiceDBEventHandler and RegistryServiceDBEventHandler to work with domain DBEventMessage
+    status: completed
+    dependencies:
+      - extend-dbevent
+  - id: verify-compilation
+    content: Verify all MessageContext usages with DBEventMessage compile correctly
+    status: completed
+    dependencies:
+      - extend-dbevent
+      - add-constructor
+      - fix-message-consumer
+      - update-handlers
+---
+
+# DBEventMessage extends MessagingEvent Integration
+
+## Problem
+
+- `MessageContext` expects `MessagingEvent` but `DBEventMessage` doesn't extend it
+- `DBEventMessage` is being passed to `MessageContext` constructors causing type errors
+- Other event types (`ProcessSubmitEvent`, `TaskStatusChangeEvent`, etc.) all extend `MessagingEvent`
+- `DBEventMessageHandler` has a TODO and missing constructor `new DBEventMessage(messageContext)`
+
+## Solution
+
+Make `DBEventMessage` extend `MessagingEvent` to align with the existing event hierarchy pattern.
+
+## Implementation Steps
+
+### 1. Update DBEventMessage to extend MessagingEvent
+
+- **File**: `airavata-api/src/main/java/org/apache/airavata/common/model/DBEventMessage.java`
+- Change class declaration: `public class DBEventMessage extends MessagingEvent`
+- This allows `DBEventMessage` to be used in `MessageContext` constructors
+
+### 2. Add constructor to extract DBEventMessage from MessageContext
+
+- **File**: `airavata-api/src/main/java/org/apache/airavata/common/model/DBEventMessage.java`
+- Add constructor: `public DBEventMessage(MessageContext messageContext)`
+- Implementation: Extract the event from `messageContext.getEvent()` and cast to `DBEventMessage`
+- This fixes the TODO in `DBEventMessageHandler` line 85
+
+### 3. Fix MessageConsumer to handle domain models
+
+- **File**: `airavata-api/src/main/java/org/apache/airavata/messaging/core/impl/MessageConsumer.java`
+- Current issue: Line 62 tries to deserialize Thrift bytes into domain model `DBEventMessage` using `ThriftUtils.createThriftFromBytes()`, but domain models don't implement `TBase`
+- Solution: Deserialize into Thrift model first, then convert to domain model using mapper, OR check if event is already a domain model
+- Since `message.getEvent()` returns `ByteBuffer`, we need to deserialize it. If the message type is `DB_EVENT`, we should deserialize to Thrift `DBEventMessage` first, then map to domain model
+
+### 4. Update DBEventPublisherUtils
+
+- **File**: `airavata-api/src/main/java/org/apache/airavata/messaging/core/util/DBEventPublisherUtils.java`
+- Line 117: `new MessageContext(dbEventMessage, MessageType.DB_EVENT, "", "")` - this will now work since `DBEventMessage` extends `MessagingEvent`
+- No changes needed, but verify it compiles
+
+### 5. Update other DB event handlers
+
+- **Files**: 
+  - `airavata-api/src/main/java/org/apache/airavata/sharing/messaging/SharingServiceDBEventHandler.java`
+  - `airavata-api/src/main/java/org/apache/airavata/registry/messaging/RegistryServiceDBEventHandler.java`
+- These handlers deserialize `DBEventMessage` from `MessageContext.getEvent()`
+- After extending `MessagingEvent`, they can cast: `(DBEventMessage) messageContext.getEvent()`
+- Update deserialization logic to work with domain models (may need mappers)
+
+### 6. Verify all MessageContext usages
+
+- Check all places where `DBEventMessage` is passed to `MessageContext` constructors
+- Ensure they compile after the change
+- Key locations:
+  - `DBEventPublisherUtils.getDBEventMessageContext()` - line 117
+  - `DBEventMessageHandler.onMessage()` - line 109
+
+## Architecture Diagram
+
+```mermaid
+classDiagram
+    class MessagingEvent {
+        <<abstract>>
+    }
+    
+    class ProcessSubmitEvent {
+        +String processId
+        +String gatewayId
+        +String experimentId
+    }
+    
+    class TaskStatusChangeEvent {
+        +TaskState state
+        +TaskIdentifier taskIdentity
+    }
+    
+    class DBEventMessage {
+        +DBEventType dbEventType
+        +DBEventMessageContext messageContext
+        +String publisherService
+        +DBEventMessage(MessageContext)
+    }
+    
+    class MessageContext {
+        -MessagingEvent event
+        -MessageType type
+        +getEvent() MessagingEvent
+    }
+    
+    MessagingEvent <|-- ProcessSubmitEvent
+    MessagingEvent <|-- TaskStatusChangeEvent
+    MessagingEvent <|-- DBEventMessage
+    MessageContext --> MessagingEvent : contains
+```
+
+## Notes
+
+- The field name `messageContext` in `DBEventMessage` (type `DBEventMessageContext`) is confusing but doesn't conflict with the `MessageContext` class
+- All other event types follow the same pattern of extending `MessagingEvent`, so this change maintains consistency
+- The constructor taking `MessageContext` will extract the event and cast it, assuming the `MessageContext` contains a `DBEventMessage` event
\ No newline at end of file
diff --git a/.cursor/plans/remove_thrift_dependencies_from_airavata-api_bf447176.plan.md b/.cursor/plans/remove_thrift_dependencies_from_airavata-api_bf447176.plan.md
new file mode 100644
index 0000000000..b430f8916b
--- /dev/null
+++ b/.cursor/plans/remove_thrift_dependencies_from_airavata-api_bf447176.plan.md
@@ -0,0 +1,158 @@
+---
+name: Remove Thrift Dependencies from airavata-api
+overview: Completely remove all Thrift dependencies from airavata-api module, replace Thrift serialization with JSON (Jackson), and restructure messaging to use OOP concepts instead of byte serialization.
+todos:
+  - id: create-message-wrapper
+    content: Create MessageWrapper class for JSON serialization of MessageContext
+    status: completed
+  - id: update-publisher-json
+    content: Update RabbitMQPublisher to use Jackson JSON serialization instead of Thrift
+    status: completed
+    dependencies:
+      - create-message-wrapper
+  - id: update-consumers-json
+    content: Update all message consumers (MessageConsumer, StatusConsumer, ExperimentConsumer, ProcessConsumer) to use Jackson JSON deserialization
+    status: completed
+    dependencies:
+      - create-message-wrapper
+  - id: update-dbevent-handlers
+    content: Remove ThriftUtils from DB event handlers and use mappers for entity data conversion
+    status: completed
+  - id: update-orchestrator-services
+    content: Remove ThriftUtils from orchestrator and task services, use mappers for task model conversion
+    status: completed
+  - id: remove-thriftutils
+    content: Delete ThriftUtils.java file completely
+    status: completed
+    dependencies:
+      - update-publisher-json
+      - update-consumers-json
+      - update-dbevent-handlers
+      - update-orchestrator-services
+  - id: remove-thrift-dependency
+    content: Remove libthrift dependency from airavata-api pom.xml
+    status: completed
+    dependencies:
+      - remove-thriftutils
+  - id: verify-no-thrift-imports
+    content: Verify no org.apache.thrift imports remain in airavata-api module
+    status: completed
+    dependencies:
+      - remove-thrift-dependency
+---
+
+# Remove Thrift Dependencies from airavata-api
+
+## Problem
+
+- `airavata-api` currently depends on Thrift libraries (`org.apache.thrift.*`)
+- Messages are serialized using Thrift binary format with ByteBuffer
+- `ThriftUtils` class provides Thrift serialization utilities
+- The messaging system uses byte serialization which is not OOP-friendly
+
+## Solution
+
+Restructure messaging to use JSON serialization with Jackson, remove all Thrift dependencies, and make the messaging system work with domain objects directly.
+
+## Implementation Steps
+
+### 1. Create JSON-serializable Message Wrapper
+
+- **File**: `airavata-api/src/main/java/org/apache/airavata/messaging/core/MessageWrapper.java`
+- Create a wrapper class that contains MessageContext fields and can be serialized to/from JSON
+- Include: event (as JSON), messageId, messageType, updatedTime, gatewayId, deliveryTag
+- Use Jackson annotations for proper serialization
+
+### 2. Update RabbitMQPublisher to use JSON
+
+- **File**: `airavata-api/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQPublisher.java`
+- Remove all `org.apache.thrift.*` imports
+- Replace Thrift serialization with Jackson ObjectMapper
+- Serialize MessageWrapper to JSON bytes
+- Remove `convertDomainEventToThrift()` method
+
+### 3. Update All Message Consumers to use JSON
+
+- **Files**:
+  - `airavata-api/src/main/java/org/apache/airavata/messaging/core/impl/MessageConsumer.java`
+  - `airavata-api/src/main/java/org/apache/airavata/messaging/core/impl/StatusConsumer.java`
+  - `airavata-api/src/main/java/org/apache/airavata/messaging/core/impl/ExperimentConsumer.java`
+  - `airavata-api/src/main/java/org/apache/airavata/messaging/core/impl/ProcessConsumer.java`
+- Remove all `org.apache.thrift.*` imports
+- Replace Thrift deserialization with Jackson ObjectMapper
+- Deserialize JSON bytes to MessageWrapper, then reconstruct MessageContext
+- Use mappers (via reflection) to convert event JSON to domain models
+
+### 4. Update DB Event Handlers
+
+- **Files**:
+  - `airavata-api/src/main/java/org/apache/airavata/sharing/messaging/SharingServiceDBEventHandler.java`
+  - `airavata-api/src/main/java/org/apache/airavata/registry/messaging/RegistryServiceDBEventHandler.java`
+  - `airavata-api/src/main/java/org/apache/airavata/messaging/core/util/DBEventPublisherUtils.java`
+- Remove ThriftUtils usage
+- For entity data models: Use mappers to convert Thrift models (from entityDataModel ByteBuffer) to domain models
+- Remove Thrift serialization calls
+
+### 5. Update Orchestrator and Task Services
+
+- **Files**:
+  - `airavata-api/src/main/java/org/apache/airavata/orchestrator/impl/SimpleOrchestratorImpl.java`
+  - `airavata-api/src/main/java/org/apache/airavata/service/orchestrator/OrchestratorService.java`
+- Remove ThriftUtils usage for task model serialization
+- Use mappers to convert domain task models to Thrift models when needed for storage
+- Store task models as JSON or use mappers for conversion
+
+### 6. Update MessageContext and Related Classes
+
+- **File**: `airavata-api/src/main/java/org/apache/airavata/messaging/core/MessageContext.java`
+- Ensure it works with domain models only (no Thrift dependencies)
+- Add JSON serialization support if needed
+
+### 7. Remove ThriftUtils Class
+
+- **File**: `airavata-api/src/main/java/org/apache/airavata/common/utils/ThriftUtils.java`
+- Delete the file completely
+- The `close()` method for TServiceClient should be moved to thrift-api module if still needed
+
+### 8. Update Maven Dependencies
+
+- **File**: `airavata-api/pom.xml`
+- Remove `libthrift` dependency
+- Ensure Jackson dependencies are present (already included)
+- Remove any Thrift-related plugin configurations
+
+### 9. Update Message Domain Model
+
+- **File**: `airavata-api/src/main/java/org/apache/airavata/common/model/Message.java`
+- Consider if this class is still needed or if MessageWrapper replaces it
+- If keeping, ensure it has no Thrift dependencies
+
+### 10. Handle Entity Data Model Serialization
+
+- For DB events, the `entityDataModel` ByteBuffer contains Thrift-serialized data
+- Use mappers to convert: ByteBuffer → Thrift model → Domain model
+- Or store entity data as JSON in the future
+
+## Architecture Changes
+
+### Before:
+
+```
+MessageContext (domain) → Thrift serialization → ByteBuffer → RabbitMQ
+RabbitMQ → ByteBuffer → Thrift deserialization → MessageContext (domain)
+```
+
+### After:
+
+```
+MessageContext (domain) → MessageWrapper (JSON) → JSON bytes → RabbitMQ
+RabbitMQ → JSON bytes → MessageWrapper (JSON) → MessageContext (domain)
+```
+
+## Notes
+
+- Jackson is already a dependency (via Spring Boot)
+- All event types extend MessagingEvent, so they can be serialized as JSON
+- Mappers are in thrift-api module, accessed via reflection to avoid circular dependency
+- Entity data models in DB events may still need Thrift deserialization initially, but should migrate to JSON
+- The Message class with ByteBuffer event field should be replaced with MessageWrapper that has the event as a JSON-serializable object
\ No newline at end of file
diff --git a/.cursor/plans/thrift_decoupling_refactoring_244a37ca.plan.md b/.cursor/plans/thrift_decoupling_refactoring_244a37ca.plan.md
new file mode 100644
index 0000000000..093e865dc3
--- /dev/null
+++ b/.cursor/plans/thrift_decoupling_refactoring_244a37ca.plan.md
@@ -0,0 +1,422 @@
+---
+name: Thrift Decoupling Refactoring
+overview: Systematically decouple the codebase from thrift-generated classes by creating domain models, moving thrift code to a separate module, and introducing mappers between domain and thrift models.
+todos:
+  - id: analyze-thrift-models
+    content: Analyze all ~170 thrift-generated model classes to understand structure, fields, and relationships
+    status: completed
+  - id: create-domain-models
+    content: Create ~170 domain model classes in org.apache.airavata.common.model.* (POJOs without thrift dependencies)
+    status: completed
+    dependencies:
+      - analyze-thrift-models
+  - id: create-domain-exceptions
+    content: Create domain exception classes to replace thrift-generated exceptions
+    status: completed
+    dependencies:
+      - analyze-thrift-models
+  - id: create-domain-enums
+    content: Extract and create domain enum classes from thrift models
+    status: completed
+    dependencies:
+      - analyze-thrift-models
+  - id: setup-mapper-infrastructure
+    content: Set up MapStruct configuration and create mapper interface structure
+    status: completed
+    dependencies:
+      - create-domain-models
+  - id: create-mappers
+    content: Create mapper interfaces for all model classes (domain ↔ thrift conversions)
+    status: completed
+    dependencies:
+      - setup-mapper-infrastructure
+  - id: create-thrift-api-module
+    content: Create modules/thrift-api/ directory structure and pom.xml
+    status: completed
+  - id: configure-thrift-generation
+    content: Configure thrift code generation in thrift-api module to output to org.apache.airavata.thriftapi.* namespace
+    status: completed
+    dependencies:
+      - create-thrift-api-module
+  - id: move-thrift-handlers
+    content: Move all handler classes from airavata-api to thrift-api module and update packages
+    status: completed
+    dependencies:
+      - create-thrift-api-module
+  - id: move-thrift-server
+    content: Move thrift server code to thrift-api module
+    status: completed
+    dependencies:
+      - create-thrift-api-module
+  - id: update-handlers-use-mappers
+    content: Update all thrift handlers to use mappers for domain ↔ thrift conversions
+    status: completed
+    dependencies:
+      - create-mappers
+      - move-thrift-handlers
+  - id: update-service-layer
+    content: Update AiravataService and all domain services to use domain models instead of thrift models
+    status: completed
+    dependencies:
+      - create-domain-models
+  - id: update-utilities
+    content: Update utility classes (ExperimentModelUtil, ProjectModelUtil, etc.) to use domain models
+    status: pending
+    dependencies:
+      - create-domain-models
+  - id: update-dependencies
+    content: "Update pom.xml files: remove thrift generation from airavata-api, add thrift-api module, update dependencies"
+    status: completed
+    dependencies:
+      - create-thrift-api-module
+  - id: update-repositories
+    content: Ensure repository/DAO layer works with domain models (update JPA entities if needed)
+    status: pending
+    dependencies:
+      - create-domain-models
+  - id: test-mappers
+    content: Create unit tests for mappers to verify domain ↔ thrift conversions
+    status: pending
+    dependencies:
+      - create-mappers
+  - id: test-services
+    content: Update and run service layer tests with domain models
+    status: pending
+    dependencies:
+      - update-service-layer
+  - id: test-thrift-server
+    content: Test thrift server startup and client connections
+    status: pending
+    dependencies:
+      - update-handlers-use-mappers
+      - move-thrift-server
+  - id: verify-compilation
+    content: Verify airavata-api compiles without thrift dependencies and compilation time improves
+    status: pending
+    dependencies:
+      - update-dependencies
+      - update-service-layer
+---
+
+# Thrift Decoupling Refactoring Plan
+
+## Overview
+
+This plan decouples the codebase from thrift-generated classes to improve compilation speed. The refactoring will:
+
+1. Create domain model classes (non-thrift) to replace direct thrift dependencies
+2. Move all thrift-related code to `org.apache.airavata.thriftapi` namespace
+3. Create a separate `thrift-api` module in `modules/` directory
+4. Introduce mappers between domain models and thrift models
+5. Update all services and handlers to use domain models with mappers
+
+## Current State Analysis
+
+- **Thrift-generated classes**: Located in `airavata-api/target/generated-sources/thrift/org/apache/airavata/common/model/` (~170 model classes)
+- **Thrift service interfaces**: `org.apache.airavata.api.model.*` (Airavata, Workflow, etc.)
+- **Thrift handlers**: `org.apache.airavata.api.thrift.handler.*` (implement thrift service interfaces)
+- **Service layer**: `org.apache.airavata.service.*` directly uses thrift-generated model classes
+- **Thrift server code**: `org.apache.airavata.api.thrift.server.*`
+
+## Target State
+
+- **Domain models**: `org.apache.airavata.common.model.*` (hand-written, non-thrift classes)
+- **Thrift models**: `org.apache.airavata.thriftapi.model.*` (in new `thrift-api` module)
+- **Thrift services**: `org.apache.airavata.thriftapi.service.*` (in new `thrift-api` module)
+- **Thrift handlers**: `org.apache.airavata.thriftapi.handler.*` (in new `thrift-api` module)
+- **Mappers**: `org.apache.airavata.thriftapi.mapper.*` (convert between domain and thrift models)
+- **Service layer**: Uses domain models only, no thrift dependencies
+
+## Implementation Plan
+
+### Phase 1: Create Domain Model Classes
+
+**Location**: `airavata-api/src/main/java/org/apache/airavata/common/model/`
+
+1. **Analyze thrift-generated models** to understand structure
+
+   - Review all ~170 classes in `target/generated-sources/thrift/org/apache/airavata/common/model/`
+   - Document field types, relationships, and enums
+
+2. **Create domain model classes** (one-to-one mapping with thrift models)
+
+   - Start with core models: `ExperimentModel`, `Project`, `Gateway`, `ApplicationInterfaceDescription`, etc.
+   - Use plain Java classes (POJOs) with:
+     - Private fields with getters/setters
+     - Constructors
+     - `equals()`, `hashCode()`, `toString()` methods
+     - No thrift dependencies
+   - Preserve all fields and types from thrift models
+   - Handle nested models (e.g., `ExperimentModel` contains `ProcessModel`)
+
+3. **Create domain exception classes**
+
+   - Move from `org.apache.airavata.common.exception.*` if they're thrift-generated
+   - Or create new ones if needed: `AiravataException`, `InvalidRequestException`, etc.
+
+4. **Create domain enum classes**
+
+   - Extract enums from thrift models: `ExperimentState`, `JobState`, `DataType`, etc.
+
+**Files to create**: ~170 domain model classes matching thrift structure
+
+### Phase 2: Create Mapper Infrastructure
+
+**Location**: `airavata-api/src/main/java/org/apache/airavata/thriftapi/mapper/`
+
+1. **Set up MapStruct** (already in dependencies)
+
+   - Create mapper interfaces using `@Mapper` annotation
+   - Generate bidirectional mappers: domain ↔ thrift
+
+2. **Create mapper interfaces**
+
+   - `ExperimentModelMapper`: `ExperimentModel` ↔ `org.apache.airavata.thriftapi.model.ExperimentModel`
+   - `ProjectMapper`: `Project` ↔ `org.apache.airavata.thriftapi.model.Project`
+   - Create mappers for all ~170 model classes
+   - Handle nested mappings (e.g., `ExperimentModel` → `ProcessModel` → `JobModel`)
+
+3. **Handle special cases**
+
+   - Enum conversions
+   - List/Collection mappings
+   - Null handling
+   - Optional fields
+
+**Key files**:
+
+- `airavata-api/src/main/java/org/apache/airavata/thriftapi/mapper/ModelMapper.java` (main mapper interface)
+- Individual mapper interfaces for each model type
+
+### Phase 3: Create Thrift-API Module
+
+**Location**: `modules/thrift-api/`
+
+1. **Create module structure**
+   ```
+   modules/thrift-api/
+   ├── pom.xml
+   └── src/main/java/org/apache/airavata/thriftapi/
+       ├── model/          (thrift-generated models)
+       ├── service/        (thrift service interfaces)
+       ├── handler/        (thrift service handlers)
+       ├── server/         (thrift server setup)
+       └── mapper/         (mappers - depends on airavata-api)
+   ```
+
+2. **Create `modules/thrift-api/pom.xml`**
+
+   - Add as module in root `pom.xml`
+   - Dependencies:
+     - `airavata-api` (for domain models and mappers)
+     - `libthrift`
+     - Spring Boot (if handlers use Spring)
+
+3. **Move thrift generation to new module**
+
+   - Update Maven configuration to generate thrift classes in `thrift-api` module
+   - Configure thrift plugin in `thrift-api/pom.xml`
+   - Output: `modules/thrift-api/target/generated-sources/thrift/org/apache/airavata/thriftapi/model/`
+
+4. **Update thrift IDL namespace** (if possible)
+
+   - Modify `.thrift` files to generate classes in `org.apache.airavata.thriftapi.*`
+   - Or use post-generation renaming/package relocation
+
+### Phase 4: Move Thrift Code to Thrift-API Module
+
+1. **Move thrift service interfaces**
+
+   - From: `airavata-api/target/generated-sources/thrift/org/apache/airavata/api/model/`
+   - To: `modules/thrift-api/target/generated-sources/thrift/org/apache/airavata/thriftapi/service/`
+
+2. **Move thrift handlers**
+
+   - From: `airavata-api/src/main/java/org/apache/airavata/api/thrift/handler/`
+   - To: `modules/thrift-api/src/main/java/org/apache/airavata/thriftapi/handler/`
+   - Update handlers to:
+     - Use domain models from `airavata-api`
+     - Use mappers to convert domain ↔ thrift
+     - Call `AiravataService` with domain models
+
+3. **Move thrift server code**
+
+   - From: `airavata-api/src/main/java/org/apache/airavata/api/thrift/server/`
+   - To: `modules/thrift-api/src/main/java/org/apache/airavata/thriftapi/server/`
+
+4. **Move thrift client code** (if any)
+
+   - From: `airavata-api/src/main/java/org/apache/airavata/api/thrift/client/`
+   - To: `modules/thrift-api/src/main/java/org/apache/airavata/thriftapi/client/`
+
+5. **Update package declarations**
+
+   - Change all `org.apache.airavata.api.thrift.*` → `org.apache.airavata.thriftapi.*`
+   - Update imports throughout moved code
+
+### Phase 5: Update Service Layer
+
+**Location**: `airavata-api/src/main/java/org/apache/airavata/service/`
+
+1. **Update `AiravataService`**
+
+   - Replace all `org.apache.airavata.common.model.*` imports (thrift) with domain model imports
+   - Update method signatures to use domain models
+   - Remove any thrift-specific code
+
+2. **Update domain services**
+
+   - `org.apache.airavata.service.experiment.ExperimentService`
+   - `org.apache.airavata.service.project.ProjectService`
+   - `org.apache.airavata.service.application.ApplicationService`
+   - All other service classes
+
+3. **Update repository/DAO layer**
+
+   - Ensure repositories work with domain models
+   - Update JPA entities if they reference thrift models
+
+4. **Update utility classes**
+
+   - `ExperimentModelUtil`, `ProjectModelUtil`, `AppInterfaceUtil`, etc.
+   - Change to use domain models
+
+### Phase 6: Update Thrift Handlers to Use Mappers
+
+**Location**: `modules/thrift-api/src/main/java/org/apache/airavata/thriftapi/handler/`
+
+1. **Update `AiravataServiceHandler`**
+   ```java
+   // Before: Direct thrift model usage
+   public Gateway getGateway(AuthzToken authzToken, String gatewayId) {
+       return airavataService.getGateway(gatewayId); // Returns thrift Gateway
+   }
+   
+   // After: Use mapper
+   public org.apache.airavata.thriftapi.model.Gateway getGateway(...) {
+       Gateway domainGateway = airavataService.getGateway(gatewayId);
+       return gatewayMapper.toThrift(domainGateway);
+   }
+   ```
+
+2. **Update all handler methods**
+
+   - Input: Convert thrift → domain using mapper
+   - Call service with domain model
+   - Output: Convert domain → thrift using mapper
+
+3. **Update all other handlers**
+
+   - `UserProfileServiceHandler`
+   - `TenantProfileServiceHandler`
+   - `SharingRegistryServerHandler`
+   - `RegistryServiceHandler`
+   - `OrchestratorServiceHandler`
+   - `IamAdminServiceHandler`
+   - `GroupManagerServiceHandler`
+   - `CredentialServiceHandler`
+
+### Phase 7: Update Dependencies and Build Configuration
+
+1. **Update `airavata-api/pom.xml`**
+
+   - Remove thrift code generation
+   - Remove direct `libthrift` dependency (or make it provided/optional)
+   - Add dependency on `thrift-api` module (for mappers)
+
+2. **Update root `pom.xml`**
+
+   - Add `modules/thrift-api` to modules list
+
+3. **Update `modules/thrift-api/pom.xml`**
+
+   - Configure thrift code generation
+   - Add dependency on `airavata-api`
+   - Configure MapStruct for mappers
+
+4. **Update build order**
+
+   - Ensure `airavata-api` compiles before `thrift-api` (for domain models)
+   - `thrift-api` generates thrift classes, then compiles mappers
+
+### Phase 8: Testing and Validation
+
+1. **Unit tests**
+
+   - Test mappers (domain ↔ thrift conversions)
+   - Test service layer with domain models
+   - Test handlers with mappers
+
+2. **Integration tests**
+
+   - Test thrift server startup
+   - Test thrift client connections
+   - Test end-to-end flows
+
+3. **Compilation verification**
+
+   - Ensure `airavata-api` compiles without thrift dependencies
+   - Verify `thrift-api` module compiles correctly
+   - Check that compilation time improves
+
+## Key Files to Modify
+
+### New Files to Create
+
+- `modules/thrift-api/pom.xml`
+- `modules/thrift-api/src/main/java/org/apache/airavata/thriftapi/**/*.java` (handlers, server)
+- `airavata-api/src/main/java/org/apache/airavata/common/model/*.java` (~170 domain model classes)
+- `airavata-api/src/main/java/org/apache/airavata/thriftapi/mapper/*.java` (mapper interfaces)
+
+### Files to Move
+
+- `airavata-api/src/main/java/org/apache/airavata/api/thrift/handler/*.java` → `modules/thrift-api/...`
+- `airavata-api/src/main/java/org/apache/airavata/api/thrift/server/*.java` → `modules/thrift-api/...`
+- `airavata-api/src/main/java/org/apache/airavata/api/thrift/client/*.java` → `modules/thrift-api/...`
+
+### Files to Update
+
+- `pom.xml` (root) - add `thrift-api` module
+- `airavata-api/pom.xml` - remove thrift generation, update dependencies
+- `airavata-api/src/main/java/org/apache/airavata/service/AiravataService.java` - use domain models
+- All service classes in `org.apache.airavata.service.*`
+- All utility classes using models
+
+## Migration Strategy
+
+**Big Bang Approach**: Create all domain models first, then migrate services and handlers.
+
+1. **Week 1-2**: Create all ~170 domain model classes
+2. **Week 3**: Create mapper infrastructure and mappers
+3. **Week 4**: Create `thrift-api` module and move thrift code
+4. **Week 5**: Update service layer to use domain models
+5. **Week 6**: Update handlers to use mappers
+6. **Week 7**: Testing and bug fixes
+
+## Risks and Mitigations
+
+1. **Risk**: Large number of models to migrate
+
+   - **Mitigation**: Use code generation tools or scripts to generate initial domain model structure from thrift models
+
+2. **Risk**: Breaking changes during migration
+
+   - **Mitigation**: Comprehensive testing, incremental commits, feature flags if possible
+
+3. **Risk**: Mapper complexity for nested models
+
+   - **Mitigation**: Use MapStruct's automatic nested mapping, test thoroughly
+
+4. **Risk**: Thrift namespace changes breaking external clients
+
+   - **Mitigation**: Keep thrift service interfaces compatible, only change internal model packages
+
+## Success Criteria
+
+- ✅ `airavata-api` module compiles without thrift dependencies
+- ✅ All services use domain models (no thrift imports)
+- ✅ All thrift code isolated in `thrift-api` module
+- ✅ Mappers correctly convert between domain and thrift models
+- ✅ Compilation time reduced (fewer dependencies to compile)
+- ✅ All tests pass
+- ✅ Thrift server still works correctly
\ No newline at end of file
diff --git a/airavata-api/pom.xml b/airavata-api/pom.xml
index 6f98e9c6e2..f438af1a28 100644
--- a/airavata-api/pom.xml
+++ b/airavata-api/pom.xml
@@ -36,10 +36,7 @@ under the License.
 
   <dependencies>
     <!-- Core libraries -->
-    <dependency>
-      <groupId>org.apache.thrift</groupId>
-      <artifactId>libthrift</artifactId>
-    </dependency>
+    <!-- Thrift dependency moved to thrift-api module -->
     <dependency>
       <groupId>org.apache.curator</groupId>
       <artifactId>curator-framework</artifactId>
@@ -153,6 +150,11 @@ under the License.
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter</artifactId>
@@ -302,6 +304,14 @@ under the License.
           <groupId>org.eclipse.angus</groupId>
           <artifactId>angus-mail</artifactId>
         </exclusion>
+        <exclusion>
+          <groupId>org.jboss.jandex</groupId>
+          <artifactId>jandex</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.jboss.resteasy</groupId>
+          <artifactId>resteasy-core</artifactId>
+        </exclusion>
       </exclusions>
     </dependency>
     <dependency>
@@ -355,11 +365,17 @@ under the License.
       <artifactId>spring-boot-starter-data-jpa</artifactId>
       <exclusions>
         <exclusion>
-          <groupId>io.smallrye</groupId>
+          <groupId>org.jboss.jandex</groupId>
           <artifactId>jandex</artifactId>
         </exclusion>
       </exclusions>
     </dependency>
+    <!-- Use io.smallrye jandex 3.x for Hibernate 6.6 compatibility -->
+    <dependency>
+      <groupId>io.smallrye</groupId>
+      <artifactId>jandex</artifactId>
+      <version>3.2.0</version>
+    </dependency>
     <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-aop</artifactId>
@@ -388,53 +404,7 @@ under the License.
         </executions>
       </plugin>
 
-      <!-- Consolidated Thrift code generation -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-antrun-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>generate-thrift-sources</id>
-            <phase>generate-sources</phase>
-            <goals>
-              <goal>run</goal>
-            </goals>
-            <configuration>
-              <target>
-                <mkdir dir="${project.build.directory}/generated-sources/thrift" />
-                <exec executable="thrift">
-                  <arg value="-r" />
-                  <arg value="--gen" />
-                  <arg value="java:beans,jakarta_annotations=undated" />
-                  <arg value="-out" />
-                  <arg value="${project.build.directory}/generated-sources/thrift" />
-                  <arg value="${project.basedir}/../thrift-interface-descriptions/stubs_java.thrift" />
-                </exec>
-              </target>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-
-      <!-- Add generated sources -->
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>build-helper-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>add-thrift-generated-sources</id>
-            <phase>generate-sources</phase>
-            <goals>
-              <goal>add-source</goal>
-            </goals>
-            <configuration>
-              <sources>
-                <source>${project.build.directory}/generated-sources/thrift</source>
-              </sources>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
+      <!-- Thrift code generation moved to thrift-api module -->
 
       <!-- Strip generated date annotations -->
       <plugin>
diff --git a/airavata-api/src/main/java/org/apache/airavata/AiravataApplication.java b/airavata-api/src/main/java/org/apache/airavata/AiravataApplication.java
index ac8802e4bd..1f744aa301 100644
--- a/airavata-api/src/main/java/org/apache/airavata/AiravataApplication.java
+++ b/airavata-api/src/main/java/org/apache/airavata/AiravataApplication.java
@@ -70,15 +70,15 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
             "org.apache.airavata.api.thrift"
         },
         excludeFilters = {
-            @org.springframework.context.annotation.ComponentScan.Filter(
+            @ComponentScan.Filter(
                     type = org.springframework.context.annotation.FilterType.REGEX,
                     pattern = ".*\\$.*" // Exclude inner classes (Thrift-generated)
                     ),
-            @org.springframework.context.annotation.ComponentScan.Filter(
+            @ComponentScan.Filter(
                     type = org.springframework.context.annotation.FilterType.REGEX,
                     pattern = ".*\\.cpi\\..*" // Exclude Thrift CPI classes
                     ),
-            @org.springframework.context.annotation.ComponentScan.Filter(
+            @ComponentScan.Filter(
                     type = org.springframework.context.annotation.FilterType.REGEX,
                     pattern = "org\\.apache\\.airavata\\.model\\..*" // Exclude Thrift-generated model classes
                     )
diff --git a/airavata-api/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountManager.java b/airavata-api/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountManager.java
index b2b401644a..5390c75a58 100644
--- a/airavata-api/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountManager.java
+++ b/airavata-api/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountManager.java
@@ -88,7 +88,7 @@ public class SSHAccountManager {
         }
 
         // get the account provisioner and config values for the preferences
-        if (!computeResourcePreference.isSetSshAccountProvisioner()) {
+        if (computeResourcePreference.getSshAccountProvisioner() == null) {
             throw new InvalidSetupException("Compute resource [" + computeResourceId
                     + "] does not have an SSH Account Provisioner configured for it.");
         }
@@ -147,7 +147,7 @@ public class SSHAccountManager {
         }
 
         // get the account provisioner and config values for the preferences
-        if (!computeResourcePreference.isSetSshAccountProvisioner()) {
+        if (computeResourcePreference.getSshAccountProvisioner() == null) {
             throw new InvalidSetupException("Compute resource [" + computeResourceId
                     + "] does not have an SSH Account Provisioner " + "configured for it.");
         }
diff --git a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/ThriftUtils.java b/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/ThriftUtils.java
deleted file mode 100644
index 5dc38d2fab..0000000000
--- a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/ThriftUtils.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
-*
-* 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
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* 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.airavata.api.thrift.util;
-
-import org.apache.airavata.common.model.DataStagingTaskModel;
-import org.apache.airavata.common.model.EnvironmentSetupTaskModel;
-import org.apache.airavata.common.model.JobSubmissionTaskModel;
-import org.apache.airavata.common.model.MonitorTaskModel;
-import org.apache.airavata.common.model.TaskModel;
-import org.apache.thrift.TBase;
-import org.apache.thrift.TDeserializer;
-import org.apache.thrift.TException;
-import org.apache.thrift.TSerializer;
-import org.apache.thrift.TServiceClient;
-
-public class ThriftUtils {
-    public static byte[] serializeThriftObject(TBase<?, ?> object) throws TException {
-        return new TSerializer().serialize(object);
-    }
-
-    public static void createThriftFromBytes(byte[] bytes, TBase<?, ?> object) throws TException {
-        new TDeserializer().deserialize(object, bytes);
-    }
-
-    public static Object getSubTaskModel(TaskModel taskModel) throws TException {
-        switch (taskModel.getTaskType()) {
-            case DATA_STAGING:
-            case OUTPUT_FETCHING:
-                DataStagingTaskModel dataStagingTaskModel = new DataStagingTaskModel();
-                ThriftUtils.createThriftFromBytes(taskModel.getSubTaskModel(), dataStagingTaskModel);
-                return dataStagingTaskModel;
-            case ENV_SETUP:
-                EnvironmentSetupTaskModel environmentSetupTaskModel = new EnvironmentSetupTaskModel();
-                ThriftUtils.createThriftFromBytes(taskModel.getSubTaskModel(), environmentSetupTaskModel);
-                return environmentSetupTaskModel;
-            case JOB_SUBMISSION:
-                JobSubmissionTaskModel jobSubmissionTaskModel = new JobSubmissionTaskModel();
-                ThriftUtils.createThriftFromBytes(taskModel.getSubTaskModel(), jobSubmissionTaskModel);
-                return jobSubmissionTaskModel;
-            case MONITORING:
-                MonitorTaskModel monitorTaskModel = new MonitorTaskModel();
-                ThriftUtils.createThriftFromBytes(taskModel.getSubTaskModel(), monitorTaskModel);
-                return monitorTaskModel;
-            case ENV_CLEANUP: // TODO return Environment Clean up task model
-            default:
-                return null;
-        }
-    }
-
-    public static void close(TServiceClient client) {
-        if (client.getOutputProtocol().getTransport().isOpen()) {
-            client.getOutputProtocol().getTransport().close();
-        }
-        if (client.getInputProtocol().getTransport().isOpen()) {
-            client.getInputProtocol().getTransport().close();
-        }
-    }
-}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/exception/AiravataClientException.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/AiravataClientException.java
new file mode 100644
index 0000000000..8fa179eccc
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/AiravataClientException.java
@@ -0,0 +1,65 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.exception;
+
+/**
+ * Domain exception: AiravataClientException
+ */
+public class AiravataClientException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private AiravataErrorType airavataErrorType;
+    private String parameter;
+
+    public AiravataClientException() {
+        super();
+    }
+
+    public AiravataClientException(String message) {
+        super(message);
+    }
+
+    public AiravataClientException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public AiravataClientException(String message, AiravataErrorType airavataErrorType, String parameter) {
+        super(message);
+        this.airavataErrorType = airavataErrorType;
+        this.parameter = parameter;
+    }
+
+    public AiravataErrorType getAiravataErrorType() {
+        return airavataErrorType;
+    }
+
+    public void setAiravataErrorType(AiravataErrorType airavataErrorType) {
+        this.airavataErrorType = airavataErrorType;
+    }
+
+    public String getParameter() {
+        return parameter;
+    }
+
+    public void setParameter(String parameter) {
+        this.parameter = parameter;
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/exception/AiravataErrorType.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/AiravataErrorType.java
new file mode 100644
index 0000000000..f9425063b8
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/AiravataErrorType.java
@@ -0,0 +1,67 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.exception;
+
+/**
+ * Domain enum: AiravataErrorType
+ */
+public enum AiravataErrorType {
+    UNKNOWN(0),
+    PERMISSION_DENIED(1),
+    INTERNAL_ERROR(2),
+    AUTHENTICATION_FAILURE(3),
+    INVALID_AUTHORIZATION(4),
+    AUTHORIZATION_EXPIRED(5),
+    UNKNOWN_GATEWAY_ID(6),
+    UNSUPPORTED_OPERATION(7);
+
+    private final int value;
+
+    AiravataErrorType(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static AiravataErrorType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return UNKNOWN;
+            case 1:
+                return PERMISSION_DENIED;
+            case 2:
+                return INTERNAL_ERROR;
+            case 3:
+                return AUTHENTICATION_FAILURE;
+            case 4:
+                return INVALID_AUTHORIZATION;
+            case 5:
+                return AUTHORIZATION_EXPIRED;
+            case 6:
+                return UNKNOWN_GATEWAY_ID;
+            case 7:
+                return UNSUPPORTED_OPERATION;
+            default:
+                return null;
+        }
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/exception/AiravataSystemException.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/AiravataSystemException.java
new file mode 100644
index 0000000000..16ece96825
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/AiravataSystemException.java
@@ -0,0 +1,55 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.exception;
+
+/**
+ * Domain exception: AiravataSystemException
+ */
+public class AiravataSystemException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private AiravataErrorType airavataErrorType;
+
+    public AiravataSystemException() {
+        super();
+    }
+
+    public AiravataSystemException(String message) {
+        super(message);
+    }
+
+    public AiravataSystemException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public AiravataSystemException(String message, AiravataErrorType airavataErrorType) {
+        super(message);
+        this.airavataErrorType = airavataErrorType;
+    }
+
+    public AiravataErrorType getAiravataErrorType() {
+        return airavataErrorType;
+    }
+
+    public void setAiravataErrorType(AiravataErrorType airavataErrorType) {
+        this.airavataErrorType = airavataErrorType;
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/AuthenticationException.java
similarity index 55%
copy from airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
copy to airavata-api/src/main/java/org/apache/airavata/common/exception/AuthenticationException.java
index c7599da358..ead65834b7 100644
--- a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/AuthenticationException.java
@@ -17,23 +17,35 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.config;
-
-import com.github.dozermapper.core.DozerBeanMapperBuilder;
-import com.github.dozermapper.core.Mapper;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+package org.apache.airavata.common.exception;
 
 /**
- * Configuration for Dozer mapper bean.
- * Replaces the three ObjectMapperSingleton classes with a single Spring-managed bean.
+ * Domain exception: AuthenticationException
  */
-@Configuration
-public class DozerMapperConfig {
-    @Bean
-    public Mapper dozerMapper() {
-        return DozerBeanMapperBuilder.create()
-                .withMappingFiles("dozer_mapping.xml")
-                .build();
+public class AuthenticationException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private String message;
+
+    public AuthenticationException() {
+        super();
+    }
+
+    public AuthenticationException(String message) {
+        super(message);
+    }
+
+    public AuthenticationException(String message, Throwable cause) {
+        super(message, cause);
+        this.message = message;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/AuthorizationException.java
similarity index 55%
copy from airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
copy to airavata-api/src/main/java/org/apache/airavata/common/exception/AuthorizationException.java
index c7599da358..64dcef58d2 100644
--- a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/AuthorizationException.java
@@ -17,23 +17,35 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.config;
-
-import com.github.dozermapper.core.DozerBeanMapperBuilder;
-import com.github.dozermapper.core.Mapper;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+package org.apache.airavata.common.exception;
 
 /**
- * Configuration for Dozer mapper bean.
- * Replaces the three ObjectMapperSingleton classes with a single Spring-managed bean.
+ * Domain exception: AuthorizationException
  */
-@Configuration
-public class DozerMapperConfig {
-    @Bean
-    public Mapper dozerMapper() {
-        return DozerBeanMapperBuilder.create()
-                .withMappingFiles("dozer_mapping.xml")
-                .build();
+public class AuthorizationException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private String message;
+
+    public AuthorizationException() {
+        super();
+    }
+
+    public AuthorizationException(String message) {
+        super(message);
+    }
+
+    public AuthorizationException(String message, Throwable cause) {
+        super(message, cause);
+        this.message = message;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/DuplicateEntryException.java
similarity index 55%
copy from airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
copy to airavata-api/src/main/java/org/apache/airavata/common/exception/DuplicateEntryException.java
index c7599da358..e609fb92b0 100644
--- a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/DuplicateEntryException.java
@@ -17,23 +17,35 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.config;
-
-import com.github.dozermapper.core.DozerBeanMapperBuilder;
-import com.github.dozermapper.core.Mapper;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+package org.apache.airavata.common.exception;
 
 /**
- * Configuration for Dozer mapper bean.
- * Replaces the three ObjectMapperSingleton classes with a single Spring-managed bean.
+ * Domain exception: DuplicateEntryException
  */
-@Configuration
-public class DozerMapperConfig {
-    @Bean
-    public Mapper dozerMapper() {
-        return DozerBeanMapperBuilder.create()
-                .withMappingFiles("dozer_mapping.xml")
-                .build();
+public class DuplicateEntryException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private String message;
+
+    public DuplicateEntryException() {
+        super();
+    }
+
+    public DuplicateEntryException(String message) {
+        super(message);
+    }
+
+    public DuplicateEntryException(String message, Throwable cause) {
+        super(message, cause);
+        this.message = message;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/exception/ExceptionHandlerUtil.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/ExceptionHandlerUtil.java
index 3f2e44c8b1..3c84669889 100644
--- a/airavata-api/src/main/java/org/apache/airavata/common/exception/ExceptionHandlerUtil.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/ExceptionHandlerUtil.java
@@ -52,11 +52,7 @@ public class ExceptionHandlerUtil {
             Logger logger, String operation, AiravataErrorType errorType, Throwable exception) {
         String message = String.format("[%s] failed: %s", operation, exception.getMessage());
         LoggingUtil.logError(logger, operation, exception.getMessage(), exception);
-
-        AiravataSystemException airavataException = new AiravataSystemException(errorType);
-        airavataException.setMessage(message);
-        airavataException.initCause(exception);
-        return airavataException;
+        return new AiravataSystemException(message, exception);
     }
 
     /**
@@ -84,11 +80,7 @@ public class ExceptionHandlerUtil {
             context.forEach((key, value) -> message.append(String.format("%s=%s, ", key, value)));
             message.setLength(message.length() - 2);
         }
-
-        AiravataSystemException airavataException = new AiravataSystemException(errorType);
-        airavataException.setMessage(message.toString());
-        airavataException.initCause(exception);
-        return airavataException;
+        return new AiravataSystemException(message.toString(), exception);
     }
 
     /**
@@ -129,12 +121,7 @@ public class ExceptionHandlerUtil {
      */
     public static AiravataSystemException wrapAsAiravataException(
             AiravataErrorType errorType, String message, Throwable cause) {
-        AiravataSystemException exception = new AiravataSystemException(errorType);
-        exception.setMessage(message);
-        if (cause != null) {
-            exception.initCause(cause);
-        }
-        return exception;
+        return new AiravataSystemException(message, cause);
     }
 
     /**
diff --git a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/ExperimentNotFoundException.java
similarity index 54%
copy from airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
copy to airavata-api/src/main/java/org/apache/airavata/common/exception/ExperimentNotFoundException.java
index c7599da358..4cdf9bfb27 100644
--- a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/ExperimentNotFoundException.java
@@ -17,23 +17,35 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.config;
-
-import com.github.dozermapper.core.DozerBeanMapperBuilder;
-import com.github.dozermapper.core.Mapper;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+package org.apache.airavata.common.exception;
 
 /**
- * Configuration for Dozer mapper bean.
- * Replaces the three ObjectMapperSingleton classes with a single Spring-managed bean.
+ * Domain exception: ExperimentNotFoundException
  */
-@Configuration
-public class DozerMapperConfig {
-    @Bean
-    public Mapper dozerMapper() {
-        return DozerBeanMapperBuilder.create()
-                .withMappingFiles("dozer_mapping.xml")
-                .build();
+public class ExperimentNotFoundException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private String message;
+
+    public ExperimentNotFoundException() {
+        super();
+    }
+
+    public ExperimentNotFoundException(String message) {
+        super(message);
+    }
+
+    public ExperimentNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+        this.message = message;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/InvalidRequestException.java
similarity index 55%
copy from airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
copy to airavata-api/src/main/java/org/apache/airavata/common/exception/InvalidRequestException.java
index c7599da358..ba1b0704bf 100644
--- a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/InvalidRequestException.java
@@ -17,23 +17,35 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.config;
-
-import com.github.dozermapper.core.DozerBeanMapperBuilder;
-import com.github.dozermapper.core.Mapper;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+package org.apache.airavata.common.exception;
 
 /**
- * Configuration for Dozer mapper bean.
- * Replaces the three ObjectMapperSingleton classes with a single Spring-managed bean.
+ * Domain exception: InvalidRequestException
  */
-@Configuration
-public class DozerMapperConfig {
-    @Bean
-    public Mapper dozerMapper() {
-        return DozerBeanMapperBuilder.create()
-                .withMappingFiles("dozer_mapping.xml")
-                .build();
+public class InvalidRequestException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private String message;
+
+    public InvalidRequestException() {
+        super();
+    }
+
+    public InvalidRequestException(String message) {
+        super(message);
+    }
+
+    public InvalidRequestException(String message, Throwable cause) {
+        super(message, cause);
+        this.message = message;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/exception/LaunchValidationException.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/LaunchValidationException.java
new file mode 100644
index 0000000000..ab0adcf97a
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/LaunchValidationException.java
@@ -0,0 +1,65 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.exception;
+
+/**
+ * Domain exception: LaunchValidationException
+ */
+public class LaunchValidationException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private ValidationResults validationResult;
+    private String errorMessage;
+
+    public LaunchValidationException() {
+        super();
+    }
+
+    public LaunchValidationException(String message) {
+        super(message);
+    }
+
+    public LaunchValidationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public LaunchValidationException(String message, ValidationResults validationResult, String errorMessage) {
+        super(message);
+        this.validationResult = validationResult;
+        this.errorMessage = errorMessage;
+    }
+
+    public ValidationResults getValidationResult() {
+        return validationResult;
+    }
+
+    public void setValidationResult(ValidationResults validationResult) {
+        this.validationResult = validationResult;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/ProjectNotFoundException.java
similarity index 53%
copy from airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
copy to airavata-api/src/main/java/org/apache/airavata/common/exception/ProjectNotFoundException.java
index c7599da358..64cc4684a4 100644
--- a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/ProjectNotFoundException.java
@@ -17,23 +17,36 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.config;
-
-import com.github.dozermapper.core.DozerBeanMapperBuilder;
-import com.github.dozermapper.core.Mapper;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+package org.apache.airavata.common.exception;
 
 /**
- * Configuration for Dozer mapper bean.
- * Replaces the three ObjectMapperSingleton classes with a single Spring-managed bean.
+ * Domain exception: ProjectNotFoundException
  */
-@Configuration
-public class DozerMapperConfig {
-    @Bean
-    public Mapper dozerMapper() {
-        return DozerBeanMapperBuilder.create()
-                .withMappingFiles("dozer_mapping.xml")
-                .build();
+public class ProjectNotFoundException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private String message;
+
+    public ProjectNotFoundException() {
+        super();
+    }
+
+    public ProjectNotFoundException(String message) {
+        super(message);
+        this.message = message;
+    }
+
+    public ProjectNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+        this.message = message;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/AiravataServiceConstants.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/TimedOutException.java
similarity index 64%
copy from airavata-api/src/main/java/org/apache/airavata/api/thrift/util/AiravataServiceConstants.java
copy to airavata-api/src/main/java/org/apache/airavata/common/exception/TimedOutException.java
index df2be727e3..bb2b6061b4 100644
--- a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/AiravataServiceConstants.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/TimedOutException.java
@@ -17,10 +17,24 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.util;
+package org.apache.airavata.common.exception;
 
-public class AiravataServiceConstants {
-    public static final String API_SERVER_PORT = "apiserver.port";
-    public static final String API_SERVER_HOST = "apiserver.host";
-    public static final String API_SERVER_MIN_THREADS = "apiserver.server.min.threads";
+/**
+ * Domain exception: TimedOutException
+ */
+public class TimedOutException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    public TimedOutException() {
+        super();
+    }
+
+    public TimedOutException(String message) {
+        super(message);
+    }
+
+    public TimedOutException(String message, Throwable cause) {
+        super(message, cause);
+    }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/exception/ValidationResults.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/ValidationResults.java
new file mode 100644
index 0000000000..420c27e87e
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/ValidationResults.java
@@ -0,0 +1,66 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.exception;
+
+/**
+ * Domain exception: ValidationResults
+ */
+public class ValidationResults extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private boolean validationState;
+    private java.util.List<ValidatorResult> validationResultList;
+
+    public ValidationResults() {
+        super();
+    }
+
+    public ValidationResults(String message) {
+        super(message);
+    }
+
+    public ValidationResults(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ValidationResults(
+            String message, boolean validationState, java.util.List<ValidatorResult> validationResultList) {
+        super(message);
+        this.validationState = validationState;
+        this.validationResultList = validationResultList;
+    }
+
+    public boolean getValidationState() {
+        return validationState;
+    }
+
+    public void setValidationState(boolean validationState) {
+        this.validationState = validationState;
+    }
+
+    public java.util.List<ValidatorResult> getValidationResultList() {
+        return validationResultList;
+    }
+
+    public void setValidationResultList(java.util.List<ValidatorResult> validationResultList) {
+        this.validationResultList = validationResultList;
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/exception/ValidatorResult.java b/airavata-api/src/main/java/org/apache/airavata/common/exception/ValidatorResult.java
new file mode 100644
index 0000000000..763469929c
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/exception/ValidatorResult.java
@@ -0,0 +1,65 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.exception;
+
+/**
+ * Domain exception: ValidatorResult
+ */
+public class ValidatorResult extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private boolean result;
+    private String errorDetails;
+
+    public ValidatorResult() {
+        super();
+    }
+
+    public ValidatorResult(String message) {
+        super(message);
+    }
+
+    public ValidatorResult(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ValidatorResult(String message, boolean result, String errorDetails) {
+        super(message);
+        this.result = result;
+        this.errorDetails = errorDetails;
+    }
+
+    public boolean getResult() {
+        return result;
+    }
+
+    public void setResult(boolean result) {
+        this.result = result;
+    }
+
+    public String getErrorDetails() {
+        return errorDetails;
+    }
+
+    public void setErrorDetails(String errorDetails) {
+        this.errorDetails = errorDetails;
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/AiravataServiceConstants.java b/airavata-api/src/main/java/org/apache/airavata/common/model/AiravataCommonsConstants.java
similarity index 71%
copy from airavata-api/src/main/java/org/apache/airavata/api/thrift/util/AiravataServiceConstants.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/AiravataCommonsConstants.java
index df2be727e3..e9a2e4dbb4 100644
--- a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/AiravataServiceConstants.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/AiravataCommonsConstants.java
@@ -17,10 +17,16 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.util;
+package org.apache.airavata.common.model;
 
-public class AiravataServiceConstants {
-    public static final String API_SERVER_PORT = "apiserver.port";
-    public static final String API_SERVER_HOST = "apiserver.host";
-    public static final String API_SERVER_MIN_THREADS = "apiserver.server.min.threads";
+/**
+ * Domain constants: AiravataCommonsConstants
+ * Constants used across Airavata models.
+ */
+public class AiravataCommonsConstants {
+    public static final String DEFAULT_ID = "DO_NOT_SET_AT_CLIENTS";
+
+    private AiravataCommonsConstants() {
+        // Utility class
+    }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/AiravataWorkflow.java b/airavata-api/src/main/java/org/apache/airavata/common/model/AiravataWorkflow.java
new file mode 100644
index 0000000000..31c997f8c8
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/AiravataWorkflow.java
@@ -0,0 +1,161 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: AiravataWorkflow
+ */
+public class AiravataWorkflow {
+    private String id;
+    private String experimentId;
+    private String description;
+    private List<WorkflowApplication> applications;
+    private List<WorkflowHandler> handlers;
+    private List<WorkflowConnection> connections;
+    private List<WorkflowStatus> statuses;
+    private List<ErrorModel> errors;
+    private long createdAt;
+    private long updatedAt;
+
+    public AiravataWorkflow() {}
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getExperimentId() {
+        return experimentId;
+    }
+
+    public void setExperimentId(String experimentId) {
+        this.experimentId = experimentId;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public List<WorkflowApplication> getApplications() {
+        return applications;
+    }
+
+    public void setApplications(List<WorkflowApplication> applications) {
+        this.applications = applications;
+    }
+
+    public List<WorkflowHandler> getHandlers() {
+        return handlers;
+    }
+
+    public void setHandlers(List<WorkflowHandler> handlers) {
+        this.handlers = handlers;
+    }
+
+    public List<WorkflowConnection> getConnections() {
+        return connections;
+    }
+
+    public void setConnections(List<WorkflowConnection> connections) {
+        this.connections = connections;
+    }
+
+    public List<WorkflowStatus> getStatuses() {
+        return statuses;
+    }
+
+    public void setStatuses(List<WorkflowStatus> statuses) {
+        this.statuses = statuses;
+    }
+
+    public List<ErrorModel> getErrors() {
+        return errors;
+    }
+
+    public void setErrors(List<ErrorModel> errors) {
+        this.errors = errors;
+    }
+
+    public long getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(long createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public long getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public void setUpdatedAt(long updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        AiravataWorkflow that = (AiravataWorkflow) o;
+        return Objects.equals(id, that.id)
+                && Objects.equals(experimentId, that.experimentId)
+                && Objects.equals(description, that.description)
+                && Objects.equals(applications, that.applications)
+                && Objects.equals(handlers, that.handlers)
+                && Objects.equals(connections, that.connections)
+                && Objects.equals(statuses, that.statuses)
+                && Objects.equals(errors, that.errors)
+                && Objects.equals(createdAt, that.createdAt)
+                && Objects.equals(updatedAt, that.updatedAt);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                id,
+                experimentId,
+                description,
+                applications,
+                handlers,
+                connections,
+                statuses,
+                errors,
+                createdAt,
+                updatedAt);
+    }
+
+    @Override
+    public String toString() {
+        return "AiravataWorkflow{" + "id=" + id + ", experimentId=" + experimentId + ", description=" + description
+                + ", applications=" + applications + ", handlers=" + handlers + ", connections=" + connections
+                + ", statuses=" + statuses + ", errors=" + errors + ", createdAt=" + createdAt + ", updatedAt="
+                + updatedAt + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationDeploymentDescription.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationDeploymentDescription.java
new file mode 100644
index 0000000000..777c383bba
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationDeploymentDescription.java
@@ -0,0 +1,242 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: ApplicationDeploymentDescription
+ */
+public class ApplicationDeploymentDescription {
+    private String appDeploymentId;
+    private String appModuleId;
+    private String computeHostId;
+    private String executablePath;
+    private ApplicationParallelismType parallelism;
+    private String appDeploymentDescription;
+    private List<CommandObject> moduleLoadCmds;
+    private List<SetEnvPaths> libPrependPaths;
+    private List<SetEnvPaths> libAppendPaths;
+    private List<SetEnvPaths> setEnvironment;
+    private List<CommandObject> preJobCommands;
+    private List<CommandObject> postJobCommands;
+    private String defaultQueueName;
+    private int defaultNodeCount;
+    private int defaultCPUCount;
+    private int defaultWalltime;
+    private boolean editableByUser;
+
+    public ApplicationDeploymentDescription() {}
+
+    public String getAppDeploymentId() {
+        return appDeploymentId;
+    }
+
+    public void setAppDeploymentId(String appDeploymentId) {
+        this.appDeploymentId = appDeploymentId;
+    }
+
+    public String getAppModuleId() {
+        return appModuleId;
+    }
+
+    public void setAppModuleId(String appModuleId) {
+        this.appModuleId = appModuleId;
+    }
+
+    public String getComputeHostId() {
+        return computeHostId;
+    }
+
+    public void setComputeHostId(String computeHostId) {
+        this.computeHostId = computeHostId;
+    }
+
+    public String getExecutablePath() {
+        return executablePath;
+    }
+
+    public void setExecutablePath(String executablePath) {
+        this.executablePath = executablePath;
+    }
+
+    public ApplicationParallelismType getParallelism() {
+        return parallelism;
+    }
+
+    public void setParallelism(ApplicationParallelismType parallelism) {
+        this.parallelism = parallelism;
+    }
+
+    public String getAppDeploymentDescription() {
+        return appDeploymentDescription;
+    }
+
+    public void setAppDeploymentDescription(String appDeploymentDescription) {
+        this.appDeploymentDescription = appDeploymentDescription;
+    }
+
+    public List<CommandObject> getModuleLoadCmds() {
+        return moduleLoadCmds;
+    }
+
+    public void setModuleLoadCmds(List<CommandObject> moduleLoadCmds) {
+        this.moduleLoadCmds = moduleLoadCmds;
+    }
+
+    public List<SetEnvPaths> getLibPrependPaths() {
+        return libPrependPaths;
+    }
+
+    public void setLibPrependPaths(List<SetEnvPaths> libPrependPaths) {
+        this.libPrependPaths = libPrependPaths;
+    }
+
+    public List<SetEnvPaths> getLibAppendPaths() {
+        return libAppendPaths;
+    }
+
+    public void setLibAppendPaths(List<SetEnvPaths> libAppendPaths) {
+        this.libAppendPaths = libAppendPaths;
+    }
+
+    public List<SetEnvPaths> getSetEnvironment() {
+        return setEnvironment;
+    }
+
+    public void setSetEnvironment(List<SetEnvPaths> setEnvironment) {
+        this.setEnvironment = setEnvironment;
+    }
+
+    public List<CommandObject> getPreJobCommands() {
+        return preJobCommands;
+    }
+
+    public void setPreJobCommands(List<CommandObject> preJobCommands) {
+        this.preJobCommands = preJobCommands;
+    }
+
+    public List<CommandObject> getPostJobCommands() {
+        return postJobCommands;
+    }
+
+    public void setPostJobCommands(List<CommandObject> postJobCommands) {
+        this.postJobCommands = postJobCommands;
+    }
+
+    public String getDefaultQueueName() {
+        return defaultQueueName;
+    }
+
+    public void setDefaultQueueName(String defaultQueueName) {
+        this.defaultQueueName = defaultQueueName;
+    }
+
+    public int getDefaultNodeCount() {
+        return defaultNodeCount;
+    }
+
+    public void setDefaultNodeCount(int defaultNodeCount) {
+        this.defaultNodeCount = defaultNodeCount;
+    }
+
+    public int getDefaultCPUCount() {
+        return defaultCPUCount;
+    }
+
+    public void setDefaultCPUCount(int defaultCPUCount) {
+        this.defaultCPUCount = defaultCPUCount;
+    }
+
+    public int getDefaultWalltime() {
+        return defaultWalltime;
+    }
+
+    public void setDefaultWalltime(int defaultWalltime) {
+        this.defaultWalltime = defaultWalltime;
+    }
+
+    public boolean getEditableByUser() {
+        return editableByUser;
+    }
+
+    public void setEditableByUser(boolean editableByUser) {
+        this.editableByUser = editableByUser;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ApplicationDeploymentDescription that = (ApplicationDeploymentDescription) o;
+        return Objects.equals(appDeploymentId, that.appDeploymentId)
+                && Objects.equals(appModuleId, that.appModuleId)
+                && Objects.equals(computeHostId, that.computeHostId)
+                && Objects.equals(executablePath, that.executablePath)
+                && Objects.equals(parallelism, that.parallelism)
+                && Objects.equals(appDeploymentDescription, that.appDeploymentDescription)
+                && Objects.equals(moduleLoadCmds, that.moduleLoadCmds)
+                && Objects.equals(libPrependPaths, that.libPrependPaths)
+                && Objects.equals(libAppendPaths, that.libAppendPaths)
+                && Objects.equals(setEnvironment, that.setEnvironment)
+                && Objects.equals(preJobCommands, that.preJobCommands)
+                && Objects.equals(postJobCommands, that.postJobCommands)
+                && Objects.equals(defaultQueueName, that.defaultQueueName)
+                && Objects.equals(defaultNodeCount, that.defaultNodeCount)
+                && Objects.equals(defaultCPUCount, that.defaultCPUCount)
+                && Objects.equals(defaultWalltime, that.defaultWalltime)
+                && Objects.equals(editableByUser, that.editableByUser);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                appDeploymentId,
+                appModuleId,
+                computeHostId,
+                executablePath,
+                parallelism,
+                appDeploymentDescription,
+                moduleLoadCmds,
+                libPrependPaths,
+                libAppendPaths,
+                setEnvironment,
+                preJobCommands,
+                postJobCommands,
+                defaultQueueName,
+                defaultNodeCount,
+                defaultCPUCount,
+                defaultWalltime,
+                editableByUser);
+    }
+
+    @Override
+    public String toString() {
+        return "ApplicationDeploymentDescription{" + "appDeploymentId=" + appDeploymentId + ", appModuleId="
+                + appModuleId + ", computeHostId=" + computeHostId + ", executablePath=" + executablePath
+                + ", parallelism=" + parallelism + ", appDeploymentDescription=" + appDeploymentDescription
+                + ", moduleLoadCmds=" + moduleLoadCmds + ", libPrependPaths=" + libPrependPaths + ", libAppendPaths="
+                + libAppendPaths + ", setEnvironment=" + setEnvironment + ", preJobCommands=" + preJobCommands
+                + ", postJobCommands=" + postJobCommands + ", defaultQueueName=" + defaultQueueName
+                + ", defaultNodeCount=" + defaultNodeCount + ", defaultCPUCount=" + defaultCPUCount
+                + ", defaultWalltime=" + defaultWalltime + ", editableByUser=" + editableByUser + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationInterfaceDescription.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationInterfaceDescription.java
new file mode 100644
index 0000000000..e7a6d57066
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationInterfaceDescription.java
@@ -0,0 +1,151 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: ApplicationInterfaceDescription
+ */
+public class ApplicationInterfaceDescription {
+    private String applicationInterfaceId;
+    private String applicationName;
+    private String applicationDescription;
+    private List<String> applicationModules;
+    private List<InputDataObjectType> applicationInputs;
+    private List<OutputDataObjectType> applicationOutputs;
+    private boolean archiveWorkingDirectory;
+    private boolean hasOptionalFileInputs;
+    private boolean cleanAfterStaged;
+
+    public ApplicationInterfaceDescription() {}
+
+    public String getApplicationInterfaceId() {
+        return applicationInterfaceId;
+    }
+
+    public void setApplicationInterfaceId(String applicationInterfaceId) {
+        this.applicationInterfaceId = applicationInterfaceId;
+    }
+
+    public String getApplicationName() {
+        return applicationName;
+    }
+
+    public void setApplicationName(String applicationName) {
+        this.applicationName = applicationName;
+    }
+
+    public String getApplicationDescription() {
+        return applicationDescription;
+    }
+
+    public void setApplicationDescription(String applicationDescription) {
+        this.applicationDescription = applicationDescription;
+    }
+
+    public List<String> getApplicationModules() {
+        return applicationModules;
+    }
+
+    public void setApplicationModules(List<String> applicationModules) {
+        this.applicationModules = applicationModules;
+    }
+
+    public List<InputDataObjectType> getApplicationInputs() {
+        return applicationInputs;
+    }
+
+    public void setApplicationInputs(List<InputDataObjectType> applicationInputs) {
+        this.applicationInputs = applicationInputs;
+    }
+
+    public List<OutputDataObjectType> getApplicationOutputs() {
+        return applicationOutputs;
+    }
+
+    public void setApplicationOutputs(List<OutputDataObjectType> applicationOutputs) {
+        this.applicationOutputs = applicationOutputs;
+    }
+
+    public boolean getArchiveWorkingDirectory() {
+        return archiveWorkingDirectory;
+    }
+
+    public void setArchiveWorkingDirectory(boolean archiveWorkingDirectory) {
+        this.archiveWorkingDirectory = archiveWorkingDirectory;
+    }
+
+    public boolean getHasOptionalFileInputs() {
+        return hasOptionalFileInputs;
+    }
+
+    public void setHasOptionalFileInputs(boolean hasOptionalFileInputs) {
+        this.hasOptionalFileInputs = hasOptionalFileInputs;
+    }
+
+    public boolean getCleanAfterStaged() {
+        return cleanAfterStaged;
+    }
+
+    public void setCleanAfterStaged(boolean cleanAfterStaged) {
+        this.cleanAfterStaged = cleanAfterStaged;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ApplicationInterfaceDescription that = (ApplicationInterfaceDescription) o;
+        return Objects.equals(applicationInterfaceId, that.applicationInterfaceId)
+                && Objects.equals(applicationName, that.applicationName)
+                && Objects.equals(applicationDescription, that.applicationDescription)
+                && Objects.equals(applicationModules, that.applicationModules)
+                && Objects.equals(applicationInputs, that.applicationInputs)
+                && Objects.equals(applicationOutputs, that.applicationOutputs)
+                && Objects.equals(archiveWorkingDirectory, that.archiveWorkingDirectory)
+                && Objects.equals(hasOptionalFileInputs, that.hasOptionalFileInputs)
+                && Objects.equals(cleanAfterStaged, that.cleanAfterStaged);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                applicationInterfaceId,
+                applicationName,
+                applicationDescription,
+                applicationModules,
+                applicationInputs,
+                applicationOutputs,
+                archiveWorkingDirectory,
+                hasOptionalFileInputs,
+                cleanAfterStaged);
+    }
+
+    @Override
+    public String toString() {
+        return "ApplicationInterfaceDescription{" + "applicationInterfaceId=" + applicationInterfaceId
+                + ", applicationName=" + applicationName + ", applicationDescription=" + applicationDescription
+                + ", applicationModules=" + applicationModules + ", applicationInputs=" + applicationInputs
+                + ", applicationOutputs=" + applicationOutputs + ", archiveWorkingDirectory=" + archiveWorkingDirectory
+                + ", hasOptionalFileInputs=" + hasOptionalFileInputs + ", cleanAfterStaged=" + cleanAfterStaged + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationModule.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationModule.java
new file mode 100644
index 0000000000..9c7e0a3911
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationModule.java
@@ -0,0 +1,88 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: ApplicationModule
+ */
+public class ApplicationModule {
+    private String appModuleId;
+    private String appModuleName;
+    private String appModuleVersion;
+    private String appModuleDescription;
+
+    public ApplicationModule() {}
+
+    public String getAppModuleId() {
+        return appModuleId;
+    }
+
+    public void setAppModuleId(String appModuleId) {
+        this.appModuleId = appModuleId;
+    }
+
+    public String getAppModuleName() {
+        return appModuleName;
+    }
+
+    public void setAppModuleName(String appModuleName) {
+        this.appModuleName = appModuleName;
+    }
+
+    public String getAppModuleVersion() {
+        return appModuleVersion;
+    }
+
+    public void setAppModuleVersion(String appModuleVersion) {
+        this.appModuleVersion = appModuleVersion;
+    }
+
+    public String getAppModuleDescription() {
+        return appModuleDescription;
+    }
+
+    public void setAppModuleDescription(String appModuleDescription) {
+        this.appModuleDescription = appModuleDescription;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ApplicationModule that = (ApplicationModule) o;
+        return Objects.equals(appModuleId, that.appModuleId)
+                && Objects.equals(appModuleName, that.appModuleName)
+                && Objects.equals(appModuleVersion, that.appModuleVersion)
+                && Objects.equals(appModuleDescription, that.appModuleDescription);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(appModuleId, appModuleName, appModuleVersion, appModuleDescription);
+    }
+
+    @Override
+    public String toString() {
+        return "ApplicationModule{" + "appModuleId=" + appModuleId + ", appModuleName=" + appModuleName
+                + ", appModuleVersion=" + appModuleVersion + ", appModuleDescription=" + appModuleDescription + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationParallelismType.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationParallelismType.java
new file mode 100644
index 0000000000..a7ce96563f
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationParallelismType.java
@@ -0,0 +1,61 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+/**
+ * Domain enum: ApplicationParallelismType
+ */
+public enum ApplicationParallelismType {
+    SERIAL(0),
+    MPI(1),
+    OPENMP(2),
+    OPENMP_MPI(3),
+    CCM(4),
+    CRAY_MPI(5);
+
+    private final int value;
+
+    ApplicationParallelismType(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static ApplicationParallelismType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return SERIAL;
+            case 1:
+                return MPI;
+            case 2:
+                return OPENMP;
+            case 3:
+                return OPENMP_MPI;
+            case 4:
+                return CCM;
+            case 5:
+                return CRAY_MPI;
+            default:
+                return null;
+        }
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationState.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationState.java
new file mode 100644
index 0000000000..b29bb0925e
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationState.java
@@ -0,0 +1,70 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+/**
+ * Domain enum: ApplicationState
+ */
+public enum ApplicationState {
+    CREATED(0),
+    VALIDATED(1),
+    SCHEDULED(2),
+    LAUNCHED(3),
+    EXECUTING(4),
+    CANCELING(5),
+    CANCELED(6),
+    COMPLETED(7),
+    FAILED(8);
+
+    private final int value;
+
+    ApplicationState(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static ApplicationState findByValue(int value) {
+        switch (value) {
+            case 0:
+                return CREATED;
+            case 1:
+                return VALIDATED;
+            case 2:
+                return SCHEDULED;
+            case 3:
+                return LAUNCHED;
+            case 4:
+                return EXECUTING;
+            case 5:
+                return CANCELING;
+            case 6:
+                return CANCELED;
+            case 7:
+                return COMPLETED;
+            case 8:
+                return FAILED;
+            default:
+                return null;
+        }
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationStatus.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationStatus.java
new file mode 100644
index 0000000000..199aac8d09
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ApplicationStatus.java
@@ -0,0 +1,88 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: ApplicationStatus
+ */
+public class ApplicationStatus {
+    private String id;
+    private ApplicationState state;
+    private String description;
+    private long updatedAt;
+
+    public ApplicationStatus() {}
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public ApplicationState getState() {
+        return state;
+    }
+
+    public void setState(ApplicationState state) {
+        this.state = state;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public long getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public void setUpdatedAt(long updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ApplicationStatus that = (ApplicationStatus) o;
+        return Objects.equals(id, that.id)
+                && Objects.equals(state, that.state)
+                && Objects.equals(description, that.description)
+                && Objects.equals(updatedAt, that.updatedAt);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, state, description, updatedAt);
+    }
+
+    @Override
+    public String toString() {
+        return "ApplicationStatus{" + "id=" + id + ", state=" + state + ", description=" + description + ", updatedAt="
+                + updatedAt + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/AwsComputeResourcePreference.java b/airavata-api/src/main/java/org/apache/airavata/common/model/AwsComputeResourcePreference.java
new file mode 100644
index 0000000000..765047ce8f
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/AwsComputeResourcePreference.java
@@ -0,0 +1,80 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: AwsComputeResourcePreference
+ */
+public class AwsComputeResourcePreference {
+    private String region;
+    private String preferredAmiId;
+    private String preferredInstanceType;
+
+    public AwsComputeResourcePreference() {}
+
+    public String getRegion() {
+        return region;
+    }
+
+    public void setRegion(String region) {
+        this.region = region;
+    }
+
+    public String getPreferredAmiId() {
+        return preferredAmiId;
+    }
+
+    public void setPreferredAmiId(String preferredAmiId) {
+        this.preferredAmiId = preferredAmiId;
+    }
+
+    public String getPreferredInstanceType() {
+        return preferredInstanceType;
+    }
+
+    public void setPreferredInstanceType(String preferredInstanceType) {
+        this.preferredInstanceType = preferredInstanceType;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        AwsComputeResourcePreference that = (AwsComputeResourcePreference) o;
+        return Objects.equals(region, that.region)
+                && Objects.equals(preferredAmiId, that.preferredAmiId)
+                && Objects.equals(preferredInstanceType, that.preferredInstanceType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(region, preferredAmiId, preferredInstanceType);
+    }
+
+    @Override
+    public String toString() {
+        return "AwsComputeResourcePreference{" + "region='"
+                + region + '\'' + ", preferredAmiId='"
+                + preferredAmiId + '\'' + ", preferredInstanceType='"
+                + preferredInstanceType + '\'' + '}';
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/BatchQueue.java b/airavata-api/src/main/java/org/apache/airavata/common/model/BatchQueue.java
new file mode 100644
index 0000000000..144ead48c0
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/BatchQueue.java
@@ -0,0 +1,194 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: BatchQueue
+ */
+public class BatchQueue {
+    private String queueName;
+    private String queueDescription;
+    private int maxRunTime;
+    private int maxNodes;
+    private int maxProcessors;
+    private int maxJobsInQueue;
+    private int maxMemory;
+    private int cpuPerNode;
+    private int defaultNodeCount;
+    private int defaultCPUCount;
+    private int defaultWalltime;
+    private String queueSpecificMacros;
+    private boolean isDefaultQueue;
+
+    public BatchQueue() {}
+
+    public String getQueueName() {
+        return queueName;
+    }
+
+    public void setQueueName(String queueName) {
+        this.queueName = queueName;
+    }
+
+    public String getQueueDescription() {
+        return queueDescription;
+    }
+
+    public void setQueueDescription(String queueDescription) {
+        this.queueDescription = queueDescription;
+    }
+
+    public int getMaxRunTime() {
+        return maxRunTime;
+    }
+
+    public void setMaxRunTime(int maxRunTime) {
+        this.maxRunTime = maxRunTime;
+    }
+
+    public int getMaxNodes() {
+        return maxNodes;
+    }
+
+    public void setMaxNodes(int maxNodes) {
+        this.maxNodes = maxNodes;
+    }
+
+    public int getMaxProcessors() {
+        return maxProcessors;
+    }
+
+    public void setMaxProcessors(int maxProcessors) {
+        this.maxProcessors = maxProcessors;
+    }
+
+    public int getMaxJobsInQueue() {
+        return maxJobsInQueue;
+    }
+
+    public void setMaxJobsInQueue(int maxJobsInQueue) {
+        this.maxJobsInQueue = maxJobsInQueue;
+    }
+
+    public int getMaxMemory() {
+        return maxMemory;
+    }
+
+    public void setMaxMemory(int maxMemory) {
+        this.maxMemory = maxMemory;
+    }
+
+    public int getCpuPerNode() {
+        return cpuPerNode;
+    }
+
+    public void setCpuPerNode(int cpuPerNode) {
+        this.cpuPerNode = cpuPerNode;
+    }
+
+    public int getDefaultNodeCount() {
+        return defaultNodeCount;
+    }
+
+    public void setDefaultNodeCount(int defaultNodeCount) {
+        this.defaultNodeCount = defaultNodeCount;
+    }
+
+    public int getDefaultCPUCount() {
+        return defaultCPUCount;
+    }
+
+    public void setDefaultCPUCount(int defaultCPUCount) {
+        this.defaultCPUCount = defaultCPUCount;
+    }
+
+    public int getDefaultWalltime() {
+        return defaultWalltime;
+    }
+
+    public void setDefaultWalltime(int defaultWalltime) {
+        this.defaultWalltime = defaultWalltime;
+    }
+
+    public String getQueueSpecificMacros() {
+        return queueSpecificMacros;
+    }
+
+    public void setQueueSpecificMacros(String queueSpecificMacros) {
+        this.queueSpecificMacros = queueSpecificMacros;
+    }
+
+    public boolean getIsDefaultQueue() {
+        return isDefaultQueue;
+    }
+
+    public void setIsDefaultQueue(boolean isDefaultQueue) {
+        this.isDefaultQueue = isDefaultQueue;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        BatchQueue that = (BatchQueue) o;
+        return Objects.equals(queueName, that.queueName)
+                && Objects.equals(queueDescription, that.queueDescription)
+                && Objects.equals(maxRunTime, that.maxRunTime)
+                && Objects.equals(maxNodes, that.maxNodes)
+                && Objects.equals(maxProcessors, that.maxProcessors)
+                && Objects.equals(maxJobsInQueue, that.maxJobsInQueue)
+                && Objects.equals(maxMemory, that.maxMemory)
+                && Objects.equals(cpuPerNode, that.cpuPerNode)
+                && Objects.equals(defaultNodeCount, that.defaultNodeCount)
+                && Objects.equals(defaultCPUCount, that.defaultCPUCount)
+                && Objects.equals(defaultWalltime, that.defaultWalltime)
+                && Objects.equals(queueSpecificMacros, that.queueSpecificMacros)
+                && Objects.equals(isDefaultQueue, that.isDefaultQueue);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                queueName,
+                queueDescription,
+                maxRunTime,
+                maxNodes,
+                maxProcessors,
+                maxJobsInQueue,
+                maxMemory,
+                cpuPerNode,
+                defaultNodeCount,
+                defaultCPUCount,
+                defaultWalltime,
+                queueSpecificMacros,
+                isDefaultQueue);
+    }
+
+    @Override
+    public String toString() {
+        return "BatchQueue{" + "queueName=" + queueName + ", queueDescription=" + queueDescription + ", maxRunTime="
+                + maxRunTime + ", maxNodes=" + maxNodes + ", maxProcessors=" + maxProcessors + ", maxJobsInQueue="
+                + maxJobsInQueue + ", maxMemory=" + maxMemory + ", cpuPerNode=" + cpuPerNode + ", defaultNodeCount="
+                + defaultNodeCount + ", defaultCPUCount=" + defaultCPUCount + ", defaultWalltime=" + defaultWalltime
+                + ", queueSpecificMacros=" + queueSpecificMacros + ", isDefaultQueue=" + isDefaultQueue + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/BatchQueueResourcePolicy.java b/airavata-api/src/main/java/org/apache/airavata/common/model/BatchQueueResourcePolicy.java
new file mode 100644
index 0000000000..7e5e229a94
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/BatchQueueResourcePolicy.java
@@ -0,0 +1,127 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: BatchQueueResourcePolicy
+ */
+public class BatchQueueResourcePolicy {
+    private String resourcePolicyId;
+    private String computeResourceId;
+    private String groupResourceProfileId;
+    private String queuename;
+    private int maxAllowedNodes;
+    private int maxAllowedCores;
+    private int maxAllowedWalltime;
+
+    public BatchQueueResourcePolicy() {}
+
+    public String getResourcePolicyId() {
+        return resourcePolicyId;
+    }
+
+    public void setResourcePolicyId(String resourcePolicyId) {
+        this.resourcePolicyId = resourcePolicyId;
+    }
+
+    public String getComputeResourceId() {
+        return computeResourceId;
+    }
+
+    public void setComputeResourceId(String computeResourceId) {
+        this.computeResourceId = computeResourceId;
+    }
+
+    public String getGroupResourceProfileId() {
+        return groupResourceProfileId;
+    }
+
+    public void setGroupResourceProfileId(String groupResourceProfileId) {
+        this.groupResourceProfileId = groupResourceProfileId;
+    }
+
+    public String getQueuename() {
+        return queuename;
+    }
+
+    public void setQueuename(String queuename) {
+        this.queuename = queuename;
+    }
+
+    public int getMaxAllowedNodes() {
+        return maxAllowedNodes;
+    }
+
+    public void setMaxAllowedNodes(int maxAllowedNodes) {
+        this.maxAllowedNodes = maxAllowedNodes;
+    }
+
+    public int getMaxAllowedCores() {
+        return maxAllowedCores;
+    }
+
+    public void setMaxAllowedCores(int maxAllowedCores) {
+        this.maxAllowedCores = maxAllowedCores;
+    }
+
+    public int getMaxAllowedWalltime() {
+        return maxAllowedWalltime;
+    }
+
+    public void setMaxAllowedWalltime(int maxAllowedWalltime) {
+        this.maxAllowedWalltime = maxAllowedWalltime;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        BatchQueueResourcePolicy that = (BatchQueueResourcePolicy) o;
+        return Objects.equals(resourcePolicyId, that.resourcePolicyId)
+                && Objects.equals(computeResourceId, that.computeResourceId)
+                && Objects.equals(groupResourceProfileId, that.groupResourceProfileId)
+                && Objects.equals(queuename, that.queuename)
+                && Objects.equals(maxAllowedNodes, that.maxAllowedNodes)
+                && Objects.equals(maxAllowedCores, that.maxAllowedCores)
+                && Objects.equals(maxAllowedWalltime, that.maxAllowedWalltime);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                resourcePolicyId,
+                computeResourceId,
+                groupResourceProfileId,
+                queuename,
+                maxAllowedNodes,
+                maxAllowedCores,
+                maxAllowedWalltime);
+    }
+
+    @Override
+    public String toString() {
+        return "BatchQueueResourcePolicy{" + "resourcePolicyId=" + resourcePolicyId + ", computeResourceId="
+                + computeResourceId + ", groupResourceProfileId=" + groupResourceProfileId + ", queuename=" + queuename
+                + ", maxAllowedNodes=" + maxAllowedNodes + ", maxAllowedCores=" + maxAllowedCores
+                + ", maxAllowedWalltime=" + maxAllowedWalltime + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/CloudJobSubmission.java b/airavata-api/src/main/java/org/apache/airavata/common/model/CloudJobSubmission.java
new file mode 100644
index 0000000000..d68920713a
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/CloudJobSubmission.java
@@ -0,0 +1,110 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: CloudJobSubmission
+ */
+public class CloudJobSubmission {
+    private String jobSubmissionInterfaceId;
+    private SecurityProtocol securityProtocol;
+    private String nodeId;
+    private String executableType;
+    private ProviderName providerName;
+    private String userAccountName;
+
+    public CloudJobSubmission() {}
+
+    public String getJobSubmissionInterfaceId() {
+        return jobSubmissionInterfaceId;
+    }
+
+    public void setJobSubmissionInterfaceId(String jobSubmissionInterfaceId) {
+        this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
+    }
+
+    public SecurityProtocol getSecurityProtocol() {
+        return securityProtocol;
+    }
+
+    public void setSecurityProtocol(SecurityProtocol securityProtocol) {
+        this.securityProtocol = securityProtocol;
+    }
+
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    public String getExecutableType() {
+        return executableType;
+    }
+
+    public void setExecutableType(String executableType) {
+        this.executableType = executableType;
+    }
+
+    public ProviderName getProviderName() {
+        return providerName;
+    }
+
+    public void setProviderName(ProviderName providerName) {
+        this.providerName = providerName;
+    }
+
+    public String getUserAccountName() {
+        return userAccountName;
+    }
+
+    public void setUserAccountName(String userAccountName) {
+        this.userAccountName = userAccountName;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        CloudJobSubmission that = (CloudJobSubmission) o;
+        return Objects.equals(jobSubmissionInterfaceId, that.jobSubmissionInterfaceId)
+                && Objects.equals(securityProtocol, that.securityProtocol)
+                && Objects.equals(nodeId, that.nodeId)
+                && Objects.equals(executableType, that.executableType)
+                && Objects.equals(providerName, that.providerName)
+                && Objects.equals(userAccountName, that.userAccountName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                jobSubmissionInterfaceId, securityProtocol, nodeId, executableType, providerName, userAccountName);
+    }
+
+    @Override
+    public String toString() {
+        return "CloudJobSubmission{" + "jobSubmissionInterfaceId=" + jobSubmissionInterfaceId + ", securityProtocol="
+                + securityProtocol + ", nodeId=" + nodeId + ", executableType=" + executableType + ", providerName="
+                + providerName + ", userAccountName=" + userAccountName + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/CommandObject.java b/airavata-api/src/main/java/org/apache/airavata/common/model/CommandObject.java
new file mode 100644
index 0000000000..3dfa8d1b1c
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/CommandObject.java
@@ -0,0 +1,66 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: CommandObject
+ */
+public class CommandObject {
+    private String command;
+    private int commandOrder;
+
+    public CommandObject() {}
+
+    public String getCommand() {
+        return command;
+    }
+
+    public void setCommand(String command) {
+        this.command = command;
+    }
+
+    public int getCommandOrder() {
+        return commandOrder;
+    }
+
+    public void setCommandOrder(int commandOrder) {
+        this.commandOrder = commandOrder;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        CommandObject that = (CommandObject) o;
+        return Objects.equals(command, that.command) && Objects.equals(commandOrder, that.commandOrder);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(command, commandOrder);
+    }
+
+    @Override
+    public String toString() {
+        return "CommandObject{" + "command=" + command + ", commandOrder=" + commandOrder + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ComponentState.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ComponentState.java
new file mode 100644
index 0000000000..89756b0d80
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ComponentState.java
@@ -0,0 +1,64 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+/**
+ * Domain enum: ComponentState
+ */
+public enum ComponentState {
+    CREATED(0),
+    WAITING(1),
+    READY(2),
+    RUNNING(3),
+    COMPLETED(4),
+    FAILED(5),
+    CANCELED(6);
+
+    private final int value;
+
+    ComponentState(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static ComponentState findByValue(int value) {
+        switch (value) {
+            case 0:
+                return CREATED;
+            case 1:
+                return WAITING;
+            case 2:
+                return READY;
+            case 3:
+                return RUNNING;
+            case 4:
+                return COMPLETED;
+            case 5:
+                return FAILED;
+            case 6:
+                return CANCELED;
+            default:
+                return null;
+        }
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ComponentStatus.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ComponentStatus.java
new file mode 100644
index 0000000000..9edfd1a519
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ComponentStatus.java
@@ -0,0 +1,78 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: ComponentStatus
+ */
+public class ComponentStatus {
+    private ComponentState state;
+    private String reason;
+    private long timeofStateChange;
+
+    public ComponentStatus() {}
+
+    public ComponentState getState() {
+        return state;
+    }
+
+    public void setState(ComponentState state) {
+        this.state = state;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+    public long getTimeofStateChange() {
+        return timeofStateChange;
+    }
+
+    public void setTimeofStateChange(long timeofStateChange) {
+        this.timeofStateChange = timeofStateChange;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ComponentStatus that = (ComponentStatus) o;
+        return Objects.equals(state, that.state)
+                && Objects.equals(reason, that.reason)
+                && Objects.equals(timeofStateChange, that.timeofStateChange);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(state, reason, timeofStateChange);
+    }
+
+    @Override
+    public String toString() {
+        return "ComponentStatus{" + "state=" + state + ", reason=" + reason + ", timeofStateChange=" + timeofStateChange
+                + "}";
+    }
+}
diff --git a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ComponentType.java
similarity index 59%
copy from airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/ComponentType.java
index 705d082370..4d80581b20 100644
--- a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ComponentType.java
@@ -17,18 +17,33 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.server;
+package org.apache.airavata.common.model;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/**
+ * Domain enum: ComponentType
+ */
+public enum ComponentType {
+    APPLICATION(0),
+    HANDLER(1);
+
+    private final int value;
 
-public class TestAiravataServiceServer {
+    ComponentType(int value) {
+        this.value = value;
+    }
 
-    private static final Logger logger = LoggerFactory.getLogger(TestAiravataServiceServer.class);
+    public int getValue() {
+        return value;
+    }
 
-    public static void main(String[] args) {
-        throw new UnsupportedOperationException(
-                "AiravataServiceServer must be used within a Spring application context. "
-                        + "Use Spring Boot application or provide dependencies manually via constructor.");
+    public static ComponentType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return APPLICATION;
+            case 1:
+                return HANDLER;
+            default:
+                return null;
+        }
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ComputationalResourceSchedulingModel.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputationalResourceSchedulingModel.java
new file mode 100644
index 0000000000..d57400ee2c
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputationalResourceSchedulingModel.java
@@ -0,0 +1,196 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: ComputationalResourceSchedulingModel
+ */
+public class ComputationalResourceSchedulingModel {
+    private String resourceHostId;
+    private int totalCPUCount;
+    private int nodeCount;
+    private int numberOfThreads;
+    private String queueName;
+    private int wallTimeLimit;
+    private int totalPhysicalMemory;
+    private String chessisNumber;
+    private String staticWorkingDir;
+    private String overrideLoginUserName;
+    private String overrideScratchLocation;
+    private String overrideAllocationProjectNumber;
+    private int mGroupCount;
+
+    public ComputationalResourceSchedulingModel() {}
+
+    public String getResourceHostId() {
+        return resourceHostId;
+    }
+
+    public void setResourceHostId(String resourceHostId) {
+        this.resourceHostId = resourceHostId;
+    }
+
+    public int getTotalCPUCount() {
+        return totalCPUCount;
+    }
+
+    public void setTotalCPUCount(int totalCPUCount) {
+        this.totalCPUCount = totalCPUCount;
+    }
+
+    public int getNodeCount() {
+        return nodeCount;
+    }
+
+    public void setNodeCount(int nodeCount) {
+        this.nodeCount = nodeCount;
+    }
+
+    public int getNumberOfThreads() {
+        return numberOfThreads;
+    }
+
+    public void setNumberOfThreads(int numberOfThreads) {
+        this.numberOfThreads = numberOfThreads;
+    }
+
+    public String getQueueName() {
+        return queueName;
+    }
+
+    public void setQueueName(String queueName) {
+        this.queueName = queueName;
+    }
+
+    public int getWallTimeLimit() {
+        return wallTimeLimit;
+    }
+
+    public void setWallTimeLimit(int wallTimeLimit) {
+        this.wallTimeLimit = wallTimeLimit;
+    }
+
+    public int getTotalPhysicalMemory() {
+        return totalPhysicalMemory;
+    }
+
+    public void setTotalPhysicalMemory(int totalPhysicalMemory) {
+        this.totalPhysicalMemory = totalPhysicalMemory;
+    }
+
+    public String getChessisNumber() {
+        return chessisNumber;
+    }
+
+    public void setChessisNumber(String chessisNumber) {
+        this.chessisNumber = chessisNumber;
+    }
+
+    public String getStaticWorkingDir() {
+        return staticWorkingDir;
+    }
+
+    public void setStaticWorkingDir(String staticWorkingDir) {
+        this.staticWorkingDir = staticWorkingDir;
+    }
+
+    public String getOverrideLoginUserName() {
+        return overrideLoginUserName;
+    }
+
+    public void setOverrideLoginUserName(String overrideLoginUserName) {
+        this.overrideLoginUserName = overrideLoginUserName;
+    }
+
+    public String getOverrideScratchLocation() {
+        return overrideScratchLocation;
+    }
+
+    public void setOverrideScratchLocation(String overrideScratchLocation) {
+        this.overrideScratchLocation = overrideScratchLocation;
+    }
+
+    public String getOverrideAllocationProjectNumber() {
+        return overrideAllocationProjectNumber;
+    }
+
+    public void setOverrideAllocationProjectNumber(String overrideAllocationProjectNumber) {
+        this.overrideAllocationProjectNumber = overrideAllocationProjectNumber;
+    }
+
+    public int getMGroupCount() {
+        return mGroupCount;
+    }
+
+    public void setMGroupCount(int mGroupCount) {
+        this.mGroupCount = mGroupCount;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ComputationalResourceSchedulingModel that = (ComputationalResourceSchedulingModel) o;
+        return Objects.equals(resourceHostId, that.resourceHostId)
+                && Objects.equals(totalCPUCount, that.totalCPUCount)
+                && Objects.equals(nodeCount, that.nodeCount)
+                && Objects.equals(numberOfThreads, that.numberOfThreads)
+                && Objects.equals(queueName, that.queueName)
+                && Objects.equals(wallTimeLimit, that.wallTimeLimit)
+                && Objects.equals(totalPhysicalMemory, that.totalPhysicalMemory)
+                && Objects.equals(chessisNumber, that.chessisNumber)
+                && Objects.equals(staticWorkingDir, that.staticWorkingDir)
+                && Objects.equals(overrideLoginUserName, that.overrideLoginUserName)
+                && Objects.equals(overrideScratchLocation, that.overrideScratchLocation)
+                && Objects.equals(overrideAllocationProjectNumber, that.overrideAllocationProjectNumber)
+                && Objects.equals(mGroupCount, that.mGroupCount);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                resourceHostId,
+                totalCPUCount,
+                nodeCount,
+                numberOfThreads,
+                queueName,
+                wallTimeLimit,
+                totalPhysicalMemory,
+                chessisNumber,
+                staticWorkingDir,
+                overrideLoginUserName,
+                overrideScratchLocation,
+                overrideAllocationProjectNumber,
+                mGroupCount);
+    }
+
+    @Override
+    public String toString() {
+        return "ComputationalResourceSchedulingModel{" + "resourceHostId=" + resourceHostId + ", totalCPUCount="
+                + totalCPUCount + ", nodeCount=" + nodeCount + ", numberOfThreads=" + numberOfThreads + ", queueName="
+                + queueName + ", wallTimeLimit=" + wallTimeLimit + ", totalPhysicalMemory=" + totalPhysicalMemory
+                + ", chessisNumber=" + chessisNumber + ", staticWorkingDir=" + staticWorkingDir
+                + ", overrideLoginUserName=" + overrideLoginUserName + ", overrideScratchLocation="
+                + overrideScratchLocation + ", overrideAllocationProjectNumber=" + overrideAllocationProjectNumber
+                + ", mGroupCount=" + mGroupCount + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourceDescription.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourceDescription.java
new file mode 100644
index 0000000000..75182a684c
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourceDescription.java
@@ -0,0 +1,254 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: ComputeResourceDescription
+ */
+public class ComputeResourceDescription {
+    private String computeResourceId;
+    private String hostName;
+    private List<String> hostAliases;
+    private List<String> ipAddresses;
+    private String resourceDescription;
+    private boolean enabled;
+    private List<BatchQueue> batchQueues;
+    private java.util.Map<FileSystems, java.lang.String> fileSystems;
+    private List<JobSubmissionInterface> jobSubmissionInterfaces;
+    private List<DataMovementInterface> dataMovementInterfaces;
+    private int maxMemoryPerNode;
+    private boolean gatewayUsageReporting;
+    private String gatewayUsageModuleLoadCommand;
+    private String gatewayUsageExecutable;
+    private int cpusPerNode;
+    private int defaultNodeCount;
+    private int defaultCPUCount;
+    private int defaultWalltime;
+
+    public ComputeResourceDescription() {}
+
+    public String getComputeResourceId() {
+        return computeResourceId;
+    }
+
+    public void setComputeResourceId(String computeResourceId) {
+        this.computeResourceId = computeResourceId;
+    }
+
+    public String getHostName() {
+        return hostName;
+    }
+
+    public void setHostName(String hostName) {
+        this.hostName = hostName;
+    }
+
+    public List<String> getHostAliases() {
+        return hostAliases;
+    }
+
+    public void setHostAliases(List<String> hostAliases) {
+        this.hostAliases = hostAliases;
+    }
+
+    public List<String> getIpAddresses() {
+        return ipAddresses;
+    }
+
+    public void setIpAddresses(List<String> ipAddresses) {
+        this.ipAddresses = ipAddresses;
+    }
+
+    public String getResourceDescription() {
+        return resourceDescription;
+    }
+
+    public void setResourceDescription(String resourceDescription) {
+        this.resourceDescription = resourceDescription;
+    }
+
+    public boolean getEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public List<BatchQueue> getBatchQueues() {
+        return batchQueues;
+    }
+
+    public void setBatchQueues(List<BatchQueue> batchQueues) {
+        this.batchQueues = batchQueues;
+    }
+
+    public java.util.Map<FileSystems, java.lang.String> getFileSystems() {
+        return fileSystems;
+    }
+
+    public void setFileSystems(java.util.Map<FileSystems, java.lang.String> fileSystems) {
+        this.fileSystems = fileSystems;
+    }
+
+    public List<JobSubmissionInterface> getJobSubmissionInterfaces() {
+        return jobSubmissionInterfaces;
+    }
+
+    public void setJobSubmissionInterfaces(List<JobSubmissionInterface> jobSubmissionInterfaces) {
+        this.jobSubmissionInterfaces = jobSubmissionInterfaces;
+    }
+
+    public List<DataMovementInterface> getDataMovementInterfaces() {
+        return dataMovementInterfaces;
+    }
+
+    public void setDataMovementInterfaces(List<DataMovementInterface> dataMovementInterfaces) {
+        this.dataMovementInterfaces = dataMovementInterfaces;
+    }
+
+    public int getMaxMemoryPerNode() {
+        return maxMemoryPerNode;
+    }
+
+    public void setMaxMemoryPerNode(int maxMemoryPerNode) {
+        this.maxMemoryPerNode = maxMemoryPerNode;
+    }
+
+    public boolean getGatewayUsageReporting() {
+        return gatewayUsageReporting;
+    }
+
+    public void setGatewayUsageReporting(boolean gatewayUsageReporting) {
+        this.gatewayUsageReporting = gatewayUsageReporting;
+    }
+
+    public String getGatewayUsageModuleLoadCommand() {
+        return gatewayUsageModuleLoadCommand;
+    }
+
+    public void setGatewayUsageModuleLoadCommand(String gatewayUsageModuleLoadCommand) {
+        this.gatewayUsageModuleLoadCommand = gatewayUsageModuleLoadCommand;
+    }
+
+    public String getGatewayUsageExecutable() {
+        return gatewayUsageExecutable;
+    }
+
+    public void setGatewayUsageExecutable(String gatewayUsageExecutable) {
+        this.gatewayUsageExecutable = gatewayUsageExecutable;
+    }
+
+    public int getCpusPerNode() {
+        return cpusPerNode;
+    }
+
+    public void setCpusPerNode(int cpusPerNode) {
+        this.cpusPerNode = cpusPerNode;
+    }
+
+    public int getDefaultNodeCount() {
+        return defaultNodeCount;
+    }
+
+    public void setDefaultNodeCount(int defaultNodeCount) {
+        this.defaultNodeCount = defaultNodeCount;
+    }
+
+    public int getDefaultCPUCount() {
+        return defaultCPUCount;
+    }
+
+    public void setDefaultCPUCount(int defaultCPUCount) {
+        this.defaultCPUCount = defaultCPUCount;
+    }
+
+    public int getDefaultWalltime() {
+        return defaultWalltime;
+    }
+
+    public void setDefaultWalltime(int defaultWalltime) {
+        this.defaultWalltime = defaultWalltime;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ComputeResourceDescription that = (ComputeResourceDescription) o;
+        return Objects.equals(computeResourceId, that.computeResourceId)
+                && Objects.equals(hostName, that.hostName)
+                && Objects.equals(hostAliases, that.hostAliases)
+                && Objects.equals(ipAddresses, that.ipAddresses)
+                && Objects.equals(resourceDescription, that.resourceDescription)
+                && Objects.equals(enabled, that.enabled)
+                && Objects.equals(batchQueues, that.batchQueues)
+                && Objects.equals(fileSystems, that.fileSystems)
+                && Objects.equals(jobSubmissionInterfaces, that.jobSubmissionInterfaces)
+                && Objects.equals(dataMovementInterfaces, that.dataMovementInterfaces)
+                && Objects.equals(maxMemoryPerNode, that.maxMemoryPerNode)
+                && Objects.equals(gatewayUsageReporting, that.gatewayUsageReporting)
+                && Objects.equals(gatewayUsageModuleLoadCommand, that.gatewayUsageModuleLoadCommand)
+                && Objects.equals(gatewayUsageExecutable, that.gatewayUsageExecutable)
+                && Objects.equals(cpusPerNode, that.cpusPerNode)
+                && Objects.equals(defaultNodeCount, that.defaultNodeCount)
+                && Objects.equals(defaultCPUCount, that.defaultCPUCount)
+                && Objects.equals(defaultWalltime, that.defaultWalltime);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                computeResourceId,
+                hostName,
+                hostAliases,
+                ipAddresses,
+                resourceDescription,
+                enabled,
+                batchQueues,
+                fileSystems,
+                jobSubmissionInterfaces,
+                dataMovementInterfaces,
+                maxMemoryPerNode,
+                gatewayUsageReporting,
+                gatewayUsageModuleLoadCommand,
+                gatewayUsageExecutable,
+                cpusPerNode,
+                defaultNodeCount,
+                defaultCPUCount,
+                defaultWalltime);
+    }
+
+    @Override
+    public String toString() {
+        return "ComputeResourceDescription{" + "computeResourceId=" + computeResourceId + ", hostName=" + hostName
+                + ", hostAliases=" + hostAliases + ", ipAddresses=" + ipAddresses + ", resourceDescription="
+                + resourceDescription + ", enabled=" + enabled + ", batchQueues=" + batchQueues + ", fileSystems="
+                + fileSystems + ", jobSubmissionInterfaces=" + jobSubmissionInterfaces + ", dataMovementInterfaces="
+                + dataMovementInterfaces + ", maxMemoryPerNode=" + maxMemoryPerNode + ", gatewayUsageReporting="
+                + gatewayUsageReporting + ", gatewayUsageModuleLoadCommand=" + gatewayUsageModuleLoadCommand
+                + ", gatewayUsageExecutable=" + gatewayUsageExecutable + ", cpusPerNode=" + cpusPerNode
+                + ", defaultNodeCount=" + defaultNodeCount + ", defaultCPUCount=" + defaultCPUCount
+                + ", defaultWalltime=" + defaultWalltime + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/registry/entities/appcatalog/ComputeResourcePolicyEntity.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourcePolicy.java
similarity index 50%
copy from airavata-api/src/main/java/org/apache/airavata/registry/entities/appcatalog/ComputeResourcePolicyEntity.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourcePolicy.java
index 5175c8dc04..95f1cd81b5 100644
--- a/airavata-api/src/main/java/org/apache/airavata/registry/entities/appcatalog/ComputeResourcePolicyEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourcePolicy.java
@@ -17,55 +17,21 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.registry.entities.appcatalog;
+package org.apache.airavata.common.model;
 
-import jakarta.persistence.CollectionTable;
-import jakarta.persistence.Column;
-import jakarta.persistence.ElementCollection;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-import java.io.Serializable;
 import java.util.List;
-import org.hibernate.annotations.OnDelete;
-import org.hibernate.annotations.OnDeleteAction;
+import java.util.Objects;
 
 /**
- * The persistent class for the compute_resource_policy database table.
+ * Domain model: ComputeResourcePolicy
  */
-@Entity
-@Table(name = "COMPUTE_RESOURCE_POLICY")
-public class ComputeResourcePolicyEntity implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    @Id
-    @Column(name = "RESOURCE_POLICY_ID", nullable = false)
+public class ComputeResourcePolicy {
     private String resourcePolicyId;
-
-    @Column(name = "COMPUTE_RESOURCE_ID", nullable = false)
     private String computeResourceId;
-
-    @Column(name = "GROUP_RESOURCE_PROFILE_ID", nullable = false)
     private String groupResourceProfileId;
-
-    // TODO: Store COMPUTE_RESOURCE_ID and QUEUE_NAME in table so it can FK to BATCH_QUEUE
-    @ElementCollection(fetch = FetchType.EAGER)
-    @CollectionTable(
-            name = "COMPUTE_RESOURCE_POLICY_QUEUES",
-            joinColumns = {@JoinColumn(name = "RESOURCE_POLICY_ID")})
-    @Column(name = "QUEUE_NAME")
     private List<String> allowedBatchQueues;
 
-    @ManyToOne(targetEntity = GroupResourceProfileEntity.class)
-    @JoinColumn(name = "GROUP_RESOURCE_PROFILE_ID", nullable = false, updatable = false)
-    @OnDelete(action = OnDeleteAction.CASCADE)
-    private GroupResourceProfileEntity groupResourceProfile;
-
-    public ComputeResourcePolicyEntity() {}
+    public ComputeResourcePolicy() {}
 
     public String getResourcePolicyId() {
         return resourcePolicyId;
@@ -99,11 +65,26 @@ public class ComputeResourcePolicyEntity implements Serializable {
         this.allowedBatchQueues = allowedBatchQueues;
     }
 
-    public GroupResourceProfileEntity getGroupResourceProfile() {
-        return groupResourceProfile;
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ComputeResourcePolicy that = (ComputeResourcePolicy) o;
+        return Objects.equals(resourcePolicyId, that.resourcePolicyId)
+                && Objects.equals(computeResourceId, that.computeResourceId)
+                && Objects.equals(groupResourceProfileId, that.groupResourceProfileId)
+                && Objects.equals(allowedBatchQueues, that.allowedBatchQueues);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(resourcePolicyId, computeResourceId, groupResourceProfileId, allowedBatchQueues);
     }
 
-    public void setGroupResourceProfile(GroupResourceProfileEntity groupResourceProfile) {
-        this.groupResourceProfile = groupResourceProfile;
+    @Override
+    public String toString() {
+        return "ComputeResourcePolicy{" + "resourcePolicyId=" + resourcePolicyId + ", computeResourceId="
+                + computeResourceId + ", groupResourceProfileId=" + groupResourceProfileId + ", allowedBatchQueues="
+                + allowedBatchQueues + "}";
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourcePreference.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourcePreference.java
new file mode 100644
index 0000000000..4627d1e995
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourcePreference.java
@@ -0,0 +1,244 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: ComputeResourcePreference
+ */
+public class ComputeResourcePreference {
+    private String computeResourceId;
+    private boolean overridebyAiravata;
+    private String loginUserName;
+    private JobSubmissionProtocol preferredJobSubmissionProtocol;
+    private DataMovementProtocol preferredDataMovementProtocol;
+    private String preferredBatchQueue;
+    private String scratchLocation;
+    private String allocationProjectNumber;
+    private String resourceSpecificCredentialStoreToken;
+    private String usageReportingGatewayId;
+    private String qualityOfService;
+    private String reservation;
+    private long reservationStartTime;
+    private long reservationEndTime;
+    private String sshAccountProvisioner;
+    private java.util.Map<java.lang.String, java.lang.String> sshAccountProvisionerConfig;
+    private String sshAccountProvisionerAdditionalInfo;
+
+    public ComputeResourcePreference() {}
+
+    public String getComputeResourceId() {
+        return computeResourceId;
+    }
+
+    public void setComputeResourceId(String computeResourceId) {
+        this.computeResourceId = computeResourceId;
+    }
+
+    public boolean getOverridebyAiravata() {
+        return overridebyAiravata;
+    }
+
+    public void setOverridebyAiravata(boolean overridebyAiravata) {
+        this.overridebyAiravata = overridebyAiravata;
+    }
+
+    public String getLoginUserName() {
+        return loginUserName;
+    }
+
+    public void setLoginUserName(String loginUserName) {
+        this.loginUserName = loginUserName;
+    }
+
+    public JobSubmissionProtocol getPreferredJobSubmissionProtocol() {
+        return preferredJobSubmissionProtocol;
+    }
+
+    public void setPreferredJobSubmissionProtocol(JobSubmissionProtocol preferredJobSubmissionProtocol) {
+        this.preferredJobSubmissionProtocol = preferredJobSubmissionProtocol;
+    }
+
+    public DataMovementProtocol getPreferredDataMovementProtocol() {
+        return preferredDataMovementProtocol;
+    }
+
+    public void setPreferredDataMovementProtocol(DataMovementProtocol preferredDataMovementProtocol) {
+        this.preferredDataMovementProtocol = preferredDataMovementProtocol;
+    }
+
+    public String getPreferredBatchQueue() {
+        return preferredBatchQueue;
+    }
+
+    public void setPreferredBatchQueue(String preferredBatchQueue) {
+        this.preferredBatchQueue = preferredBatchQueue;
+    }
+
+    public String getScratchLocation() {
+        return scratchLocation;
+    }
+
+    public void setScratchLocation(String scratchLocation) {
+        this.scratchLocation = scratchLocation;
+    }
+
+    public String getAllocationProjectNumber() {
+        return allocationProjectNumber;
+    }
+
+    public void setAllocationProjectNumber(String allocationProjectNumber) {
+        this.allocationProjectNumber = allocationProjectNumber;
+    }
+
+    public String getResourceSpecificCredentialStoreToken() {
+        return resourceSpecificCredentialStoreToken;
+    }
+
+    public void setResourceSpecificCredentialStoreToken(String resourceSpecificCredentialStoreToken) {
+        this.resourceSpecificCredentialStoreToken = resourceSpecificCredentialStoreToken;
+    }
+
+    public String getUsageReportingGatewayId() {
+        return usageReportingGatewayId;
+    }
+
+    public void setUsageReportingGatewayId(String usageReportingGatewayId) {
+        this.usageReportingGatewayId = usageReportingGatewayId;
+    }
+
+    public String getQualityOfService() {
+        return qualityOfService;
+    }
+
+    public void setQualityOfService(String qualityOfService) {
+        this.qualityOfService = qualityOfService;
+    }
+
+    public String getReservation() {
+        return reservation;
+    }
+
+    public void setReservation(String reservation) {
+        this.reservation = reservation;
+    }
+
+    public long getReservationStartTime() {
+        return reservationStartTime;
+    }
+
+    public void setReservationStartTime(long reservationStartTime) {
+        this.reservationStartTime = reservationStartTime;
+    }
+
+    public long getReservationEndTime() {
+        return reservationEndTime;
+    }
+
+    public void setReservationEndTime(long reservationEndTime) {
+        this.reservationEndTime = reservationEndTime;
+    }
+
+    public String getSshAccountProvisioner() {
+        return sshAccountProvisioner;
+    }
+
+    public void setSshAccountProvisioner(String sshAccountProvisioner) {
+        this.sshAccountProvisioner = sshAccountProvisioner;
+    }
+
+    public java.util.Map<java.lang.String, java.lang.String> getSshAccountProvisionerConfig() {
+        return sshAccountProvisionerConfig;
+    }
+
+    public void setSshAccountProvisionerConfig(
+            java.util.Map<java.lang.String, java.lang.String> sshAccountProvisionerConfig) {
+        this.sshAccountProvisionerConfig = sshAccountProvisionerConfig;
+    }
+
+    public String getSshAccountProvisionerAdditionalInfo() {
+        return sshAccountProvisionerAdditionalInfo;
+    }
+
+    public void setSshAccountProvisionerAdditionalInfo(String sshAccountProvisionerAdditionalInfo) {
+        this.sshAccountProvisionerAdditionalInfo = sshAccountProvisionerAdditionalInfo;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ComputeResourcePreference that = (ComputeResourcePreference) o;
+        return Objects.equals(computeResourceId, that.computeResourceId)
+                && Objects.equals(overridebyAiravata, that.overridebyAiravata)
+                && Objects.equals(loginUserName, that.loginUserName)
+                && Objects.equals(preferredJobSubmissionProtocol, that.preferredJobSubmissionProtocol)
+                && Objects.equals(preferredDataMovementProtocol, that.preferredDataMovementProtocol)
+                && Objects.equals(preferredBatchQueue, that.preferredBatchQueue)
+                && Objects.equals(scratchLocation, that.scratchLocation)
+                && Objects.equals(allocationProjectNumber, that.allocationProjectNumber)
+                && Objects.equals(resourceSpecificCredentialStoreToken, that.resourceSpecificCredentialStoreToken)
+                && Objects.equals(usageReportingGatewayId, that.usageReportingGatewayId)
+                && Objects.equals(qualityOfService, that.qualityOfService)
+                && Objects.equals(reservation, that.reservation)
+                && Objects.equals(reservationStartTime, that.reservationStartTime)
+                && Objects.equals(reservationEndTime, that.reservationEndTime)
+                && Objects.equals(sshAccountProvisioner, that.sshAccountProvisioner)
+                && Objects.equals(sshAccountProvisionerConfig, that.sshAccountProvisionerConfig)
+                && Objects.equals(sshAccountProvisionerAdditionalInfo, that.sshAccountProvisionerAdditionalInfo);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                computeResourceId,
+                overridebyAiravata,
+                loginUserName,
+                preferredJobSubmissionProtocol,
+                preferredDataMovementProtocol,
+                preferredBatchQueue,
+                scratchLocation,
+                allocationProjectNumber,
+                resourceSpecificCredentialStoreToken,
+                usageReportingGatewayId,
+                qualityOfService,
+                reservation,
+                reservationStartTime,
+                reservationEndTime,
+                sshAccountProvisioner,
+                sshAccountProvisionerConfig,
+                sshAccountProvisionerAdditionalInfo);
+    }
+
+    @Override
+    public String toString() {
+        return "ComputeResourcePreference{" + "computeResourceId=" + computeResourceId + ", overridebyAiravata="
+                + overridebyAiravata + ", loginUserName=" + loginUserName + ", preferredJobSubmissionProtocol="
+                + preferredJobSubmissionProtocol + ", preferredDataMovementProtocol=" + preferredDataMovementProtocol
+                + ", preferredBatchQueue=" + preferredBatchQueue + ", scratchLocation=" + scratchLocation
+                + ", allocationProjectNumber=" + allocationProjectNumber + ", resourceSpecificCredentialStoreToken="
+                + resourceSpecificCredentialStoreToken + ", usageReportingGatewayId=" + usageReportingGatewayId
+                + ", qualityOfService=" + qualityOfService + ", reservation=" + reservation + ", reservationStartTime="
+                + reservationStartTime + ", reservationEndTime=" + reservationEndTime + ", sshAccountProvisioner="
+                + sshAccountProvisioner + ", sshAccountProvisionerConfig=" + sshAccountProvisionerConfig
+                + ", sshAccountProvisionerAdditionalInfo=" + sshAccountProvisionerAdditionalInfo + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourceReservation.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourceReservation.java
new file mode 100644
index 0000000000..aff42982a4
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourceReservation.java
@@ -0,0 +1,108 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: ComputeResourceReservation
+ */
+public class ComputeResourceReservation {
+    private String reservationId;
+    private String reservationName;
+    private List<String> queueNames;
+    private long startTime;
+    private long endTime;
+
+    public ComputeResourceReservation() {}
+
+    public ComputeResourceReservation(
+            String reservationId, String reservationName, List<String> queueNames, long startTime, long endTime) {
+        this.reservationId = reservationId;
+        this.reservationName = reservationName;
+        this.queueNames = queueNames;
+        this.startTime = startTime;
+        this.endTime = endTime;
+    }
+
+    public String getReservationId() {
+        return reservationId;
+    }
+
+    public void setReservationId(String reservationId) {
+        this.reservationId = reservationId;
+    }
+
+    public String getReservationName() {
+        return reservationName;
+    }
+
+    public void setReservationName(String reservationName) {
+        this.reservationName = reservationName;
+    }
+
+    public List<String> getQueueNames() {
+        return queueNames;
+    }
+
+    public void setQueueNames(List<String> queueNames) {
+        this.queueNames = queueNames;
+    }
+
+    public long getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(long startTime) {
+        this.startTime = startTime;
+    }
+
+    public long getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(long endTime) {
+        this.endTime = endTime;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ComputeResourceReservation that = (ComputeResourceReservation) o;
+        return Objects.equals(reservationId, that.reservationId)
+                && Objects.equals(reservationName, that.reservationName)
+                && Objects.equals(queueNames, that.queueNames)
+                && Objects.equals(startTime, that.startTime)
+                && Objects.equals(endTime, that.endTime);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(reservationId, reservationName, queueNames, startTime, endTime);
+    }
+
+    @Override
+    public String toString() {
+        return "ComputeResourceReservation{" + "reservationId=" + reservationId + ", reservationName=" + reservationName
+                + ", queueNames=" + queueNames + ", startTime=" + startTime + ", endTime=" + endTime + "}";
+    }
+}
diff --git a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourceType.java
similarity index 59%
copy from airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourceType.java
index 705d082370..b16022ccd7 100644
--- a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ComputeResourceType.java
@@ -17,18 +17,33 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.server;
+package org.apache.airavata.common.model;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/**
+ * Domain enum: ComputeResourceType
+ */
+public enum ComputeResourceType {
+    SLURM(0),
+    AWS(1);
+
+    private final int value;
 
-public class TestAiravataServiceServer {
+    ComputeResourceType(int value) {
+        this.value = value;
+    }
 
-    private static final Logger logger = LoggerFactory.getLogger(TestAiravataServiceServer.class);
+    public int getValue() {
+        return value;
+    }
 
-    public static void main(String[] args) {
-        throw new UnsupportedOperationException(
-                "AiravataServiceServer must be used within a Spring application context. "
-                        + "Use Spring Boot application or provide dependencies manually via constructor.");
+    public static ComputeResourceType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return SLURM;
+            case 1:
+                return AWS;
+            default:
+                return null;
+        }
     }
 }
diff --git a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java b/airavata-api/src/main/java/org/apache/airavata/common/model/CrudType.java
similarity index 58%
copy from airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/CrudType.java
index 705d082370..0a76f6ba12 100644
--- a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/CrudType.java
@@ -17,18 +17,36 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.server;
+package org.apache.airavata.common.model;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/**
+ * Domain enum: CrudType
+ */
+public enum CrudType {
+    CREATE(0),
+    UPDATE(2),
+    DELETE(3);
+
+    private final int value;
 
-public class TestAiravataServiceServer {
+    CrudType(int value) {
+        this.value = value;
+    }
 
-    private static final Logger logger = LoggerFactory.getLogger(TestAiravataServiceServer.class);
+    public int getValue() {
+        return value;
+    }
 
-    public static void main(String[] args) {
-        throw new UnsupportedOperationException(
-                "AiravataServiceServer must be used within a Spring application context. "
-                        + "Use Spring Boot application or provide dependencies manually via constructor.");
+    public static CrudType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return CREATE;
+            case 2:
+                return UPDATE;
+            case 3:
+                return DELETE;
+            default:
+                return null;
+        }
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/CustomDashboard.java b/airavata-api/src/main/java/org/apache/airavata/common/model/CustomDashboard.java
new file mode 100644
index 0000000000..1cf60c5f87
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/CustomDashboard.java
@@ -0,0 +1,330 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: CustomDashboard
+ */
+public class CustomDashboard {
+    private String airavataInternalUserId;
+    private String experimentId;
+    private String name;
+    private String description;
+    private String project;
+    private String owner;
+    private String application;
+    private String computeResource;
+    private String jobName;
+    private String jobId;
+    private String jobStatus;
+    private String jobCreationTime;
+    private String notificationsTo;
+    private String workingDir;
+    private String jobDescription;
+    private String creationTime;
+    private String lastModifiedTime;
+    private String wallTime;
+    private String cpuCount;
+    private String nodeCount;
+    private String queue;
+    private String inputs;
+    private String outputs;
+    private String storageDir;
+    private String errors;
+
+    public CustomDashboard() {}
+
+    public String getAiravataInternalUserId() {
+        return airavataInternalUserId;
+    }
+
+    public void setAiravataInternalUserId(String airavataInternalUserId) {
+        this.airavataInternalUserId = airavataInternalUserId;
+    }
+
+    public String getExperimentId() {
+        return experimentId;
+    }
+
+    public void setExperimentId(String experimentId) {
+        this.experimentId = experimentId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getProject() {
+        return project;
+    }
+
+    public void setProject(String project) {
+        this.project = project;
+    }
+
+    public String getOwner() {
+        return owner;
+    }
+
+    public void setOwner(String owner) {
+        this.owner = owner;
+    }
+
+    public String getApplication() {
+        return application;
+    }
+
+    public void setApplication(String application) {
+        this.application = application;
+    }
+
+    public String getComputeResource() {
+        return computeResource;
+    }
+
+    public void setComputeResource(String computeResource) {
+        this.computeResource = computeResource;
+    }
+
+    public String getJobName() {
+        return jobName;
+    }
+
+    public void setJobName(String jobName) {
+        this.jobName = jobName;
+    }
+
+    public String getJobId() {
+        return jobId;
+    }
+
+    public void setJobId(String jobId) {
+        this.jobId = jobId;
+    }
+
+    public String getJobStatus() {
+        return jobStatus;
+    }
+
+    public void setJobStatus(String jobStatus) {
+        this.jobStatus = jobStatus;
+    }
+
+    public String getJobCreationTime() {
+        return jobCreationTime;
+    }
+
+    public void setJobCreationTime(String jobCreationTime) {
+        this.jobCreationTime = jobCreationTime;
+    }
+
+    public String getNotificationsTo() {
+        return notificationsTo;
+    }
+
+    public void setNotificationsTo(String notificationsTo) {
+        this.notificationsTo = notificationsTo;
+    }
+
+    public String getWorkingDir() {
+        return workingDir;
+    }
+
+    public void setWorkingDir(String workingDir) {
+        this.workingDir = workingDir;
+    }
+
+    public String getJobDescription() {
+        return jobDescription;
+    }
+
+    public void setJobDescription(String jobDescription) {
+        this.jobDescription = jobDescription;
+    }
+
+    public String getCreationTime() {
+        return creationTime;
+    }
+
+    public void setCreationTime(String creationTime) {
+        this.creationTime = creationTime;
+    }
+
+    public String getLastModifiedTime() {
+        return lastModifiedTime;
+    }
+
+    public void setLastModifiedTime(String lastModifiedTime) {
+        this.lastModifiedTime = lastModifiedTime;
+    }
+
+    public String getWallTime() {
+        return wallTime;
+    }
+
+    public void setWallTime(String wallTime) {
+        this.wallTime = wallTime;
+    }
+
+    public String getCpuCount() {
+        return cpuCount;
+    }
+
+    public void setCpuCount(String cpuCount) {
+        this.cpuCount = cpuCount;
+    }
+
+    public String getNodeCount() {
+        return nodeCount;
+    }
+
+    public void setNodeCount(String nodeCount) {
+        this.nodeCount = nodeCount;
+    }
+
+    public String getQueue() {
+        return queue;
+    }
+
+    public void setQueue(String queue) {
+        this.queue = queue;
+    }
+
+    public String getInputs() {
+        return inputs;
+    }
+
+    public void setInputs(String inputs) {
+        this.inputs = inputs;
+    }
+
+    public String getOutputs() {
+        return outputs;
+    }
+
+    public void setOutputs(String outputs) {
+        this.outputs = outputs;
+    }
+
+    public String getStorageDir() {
+        return storageDir;
+    }
+
+    public void setStorageDir(String storageDir) {
+        this.storageDir = storageDir;
+    }
+
+    public String getErrors() {
+        return errors;
+    }
+
+    public void setErrors(String errors) {
+        this.errors = errors;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        CustomDashboard that = (CustomDashboard) o;
+        return Objects.equals(airavataInternalUserId, that.airavataInternalUserId)
+                && Objects.equals(experimentId, that.experimentId)
+                && Objects.equals(name, that.name)
+                && Objects.equals(description, that.description)
+                && Objects.equals(project, that.project)
+                && Objects.equals(owner, that.owner)
+                && Objects.equals(application, that.application)
+                && Objects.equals(computeResource, that.computeResource)
+                && Objects.equals(jobName, that.jobName)
+                && Objects.equals(jobId, that.jobId)
+                && Objects.equals(jobStatus, that.jobStatus)
+                && Objects.equals(jobCreationTime, that.jobCreationTime)
+                && Objects.equals(notificationsTo, that.notificationsTo)
+                && Objects.equals(workingDir, that.workingDir)
+                && Objects.equals(jobDescription, that.jobDescription)
+                && Objects.equals(creationTime, that.creationTime)
+                && Objects.equals(lastModifiedTime, that.lastModifiedTime)
+                && Objects.equals(wallTime, that.wallTime)
+                && Objects.equals(cpuCount, that.cpuCount)
+                && Objects.equals(nodeCount, that.nodeCount)
+                && Objects.equals(queue, that.queue)
+                && Objects.equals(inputs, that.inputs)
+                && Objects.equals(outputs, that.outputs)
+                && Objects.equals(storageDir, that.storageDir)
+                && Objects.equals(errors, that.errors);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                airavataInternalUserId,
+                experimentId,
+                name,
+                description,
+                project,
+                owner,
+                application,
+                computeResource,
+                jobName,
+                jobId,
+                jobStatus,
+                jobCreationTime,
+                notificationsTo,
+                workingDir,
+                jobDescription,
+                creationTime,
+                lastModifiedTime,
+                wallTime,
+                cpuCount,
+                nodeCount,
+                queue,
+                inputs,
+                outputs,
+                storageDir,
+                errors);
+    }
+
+    @Override
+    public String toString() {
+        return "CustomDashboard{" + "airavataInternalUserId=" + airavataInternalUserId + ", experimentId="
+                + experimentId + ", name=" + name + ", description=" + description + ", project=" + project + ", owner="
+                + owner + ", application=" + application + ", computeResource=" + computeResource + ", jobName="
+                + jobName + ", jobId=" + jobId + ", jobStatus=" + jobStatus + ", jobCreationTime=" + jobCreationTime
+                + ", notificationsTo=" + notificationsTo + ", workingDir=" + workingDir + ", jobDescription="
+                + jobDescription + ", creationTime=" + creationTime + ", lastModifiedTime=" + lastModifiedTime
+                + ", wallTime=" + wallTime + ", cpuCount=" + cpuCount + ", nodeCount=" + nodeCount + ", queue=" + queue
+                + ", inputs=" + inputs + ", outputs=" + outputs + ", storageDir=" + storageDir + ", errors=" + errors
+                + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventMessage.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventMessage.java
new file mode 100644
index 0000000000..612e6bdf5e
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventMessage.java
@@ -0,0 +1,94 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+import org.apache.airavata.messaging.core.MessageContext;
+
+/**
+ * Domain model: DBEventMessage
+ */
+public class DBEventMessage extends MessagingEvent {
+    private DBEventType dbEventType;
+    private DBEventMessageContext messageContext;
+    private String publisherService;
+
+    public DBEventMessage() {}
+
+    /**
+     * Constructor to extract DBEventMessage from MessageContext.
+     * Assumes the MessageContext contains a DBEventMessage event.
+     */
+    public DBEventMessage(MessageContext messageContext) {
+        if (messageContext.getEvent() instanceof DBEventMessage) {
+            DBEventMessage event = (DBEventMessage) messageContext.getEvent();
+            this.dbEventType = event.getDbEventType();
+            this.messageContext = event.getMessageContext();
+            this.publisherService = event.getPublisherService();
+        } else {
+            throw new IllegalArgumentException("MessageContext does not contain a DBEventMessage event");
+        }
+    }
+
+    public DBEventType getDbEventType() {
+        return dbEventType;
+    }
+
+    public void setDbEventType(DBEventType dbEventType) {
+        this.dbEventType = dbEventType;
+    }
+
+    public DBEventMessageContext getMessageContext() {
+        return messageContext;
+    }
+
+    public void setMessageContext(DBEventMessageContext messageContext) {
+        this.messageContext = messageContext;
+    }
+
+    public String getPublisherService() {
+        return publisherService;
+    }
+
+    public void setPublisherService(String publisherService) {
+        this.publisherService = publisherService;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DBEventMessage that = (DBEventMessage) o;
+        return Objects.equals(dbEventType, that.dbEventType)
+                && Objects.equals(messageContext, that.messageContext)
+                && Objects.equals(publisherService, that.publisherService);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(dbEventType, messageContext, publisherService);
+    }
+
+    @Override
+    public String toString() {
+        return "DBEventMessage{" + "dbEventType=" + dbEventType + ", messageContext=" + messageContext
+                + ", publisherService=" + publisherService + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventMessageContext.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventMessageContext.java
new file mode 100644
index 0000000000..90f0d7858b
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventMessageContext.java
@@ -0,0 +1,101 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: DBEventMessageContext
+ * Union type that can be either a publisher or subscriber.
+ */
+public class DBEventMessageContext {
+    private DBEventPublisher publisher;
+    private DBEventSubscriber subscriber;
+
+    public DBEventMessageContext() {}
+
+    public DBEventPublisher getPublisher() {
+        return publisher;
+    }
+
+    public void setPublisher(DBEventPublisher publisher) {
+        this.publisher = publisher;
+        this.subscriber = null; // Clear subscriber when setting publisher
+    }
+
+    public DBEventSubscriber getSubscriber() {
+        return subscriber;
+    }
+
+    public void setSubscriber(DBEventSubscriber subscriber) {
+        this.subscriber = subscriber;
+        this.publisher = null; // Clear publisher when setting subscriber
+    }
+
+    /**
+     * Static factory method to create a publisher context.
+     */
+    public static DBEventMessageContext publisher(DBEventPublisher publisher) {
+        DBEventMessageContext context = new DBEventMessageContext();
+        context.setPublisher(publisher);
+        return context;
+    }
+
+    /**
+     * Static factory method to create a subscriber context.
+     */
+    public static DBEventMessageContext subscriber(DBEventSubscriber subscriber) {
+        DBEventMessageContext context = new DBEventMessageContext();
+        context.setSubscriber(subscriber);
+        return context;
+    }
+
+    public boolean isPublisher() {
+        return publisher != null;
+    }
+
+    public boolean isSubscriber() {
+        return subscriber != null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DBEventMessageContext that = (DBEventMessageContext) o;
+        return Objects.equals(publisher, that.publisher) && Objects.equals(subscriber, that.subscriber);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(publisher, subscriber);
+    }
+
+    @Override
+    public String toString() {
+        if (publisher != null) {
+            return "DBEventMessageContext{publisher=" + publisher + "}";
+        } else if (subscriber != null) {
+            return "DBEventMessageContext{subscriber=" + subscriber + "}";
+        } else {
+            return "DBEventMessageContext{empty}";
+        }
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventPublisher.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventPublisher.java
new file mode 100644
index 0000000000..174e8d9e58
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventPublisher.java
@@ -0,0 +1,57 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: DBEventPublisher
+ */
+public class DBEventPublisher {
+    private DBEventPublisherContext publisherContext;
+
+    public DBEventPublisher() {}
+
+    public DBEventPublisherContext getPublisherContext() {
+        return publisherContext;
+    }
+
+    public void setPublisherContext(DBEventPublisherContext publisherContext) {
+        this.publisherContext = publisherContext;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DBEventPublisher that = (DBEventPublisher) o;
+        return Objects.equals(publisherContext, that.publisherContext);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(publisherContext);
+    }
+
+    @Override
+    public String toString() {
+        return "DBEventPublisher{" + "publisherContext=" + publisherContext + '}';
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventPublisherContext.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventPublisherContext.java
new file mode 100644
index 0000000000..3d9166494e
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventPublisherContext.java
@@ -0,0 +1,79 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+/**
+ * Domain model: DBEventPublisherContext
+ */
+public class DBEventPublisherContext {
+    private CrudType crudType;
+    private EntityType entityType;
+    private ByteBuffer entityDataModel;
+
+    public DBEventPublisherContext() {}
+
+    public CrudType getCrudType() {
+        return crudType;
+    }
+
+    public void setCrudType(CrudType crudType) {
+        this.crudType = crudType;
+    }
+
+    public EntityType getEntityType() {
+        return entityType;
+    }
+
+    public void setEntityType(EntityType entityType) {
+        this.entityType = entityType;
+    }
+
+    public ByteBuffer getEntityDataModel() {
+        return entityDataModel;
+    }
+
+    public void setEntityDataModel(ByteBuffer entityDataModel) {
+        this.entityDataModel = entityDataModel;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DBEventPublisherContext that = (DBEventPublisherContext) o;
+        return Objects.equals(crudType, that.crudType)
+                && Objects.equals(entityType, that.entityType)
+                && Objects.equals(entityDataModel, that.entityDataModel);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(crudType, entityType, entityDataModel);
+    }
+
+    @Override
+    public String toString() {
+        return "DBEventPublisherContext{" + "crudType=" + crudType + ", entityType=" + entityType + ", entityDataModel="
+                + entityDataModel + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventSubscriber.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventSubscriber.java
new file mode 100644
index 0000000000..f2aa186fb8
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventSubscriber.java
@@ -0,0 +1,57 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: DBEventSubscriber
+ */
+public class DBEventSubscriber {
+    private String subscriberService;
+
+    public DBEventSubscriber() {}
+
+    public String getSubscriberService() {
+        return subscriberService;
+    }
+
+    public void setSubscriberService(String subscriberService) {
+        this.subscriberService = subscriberService;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DBEventSubscriber that = (DBEventSubscriber) o;
+        return Objects.equals(subscriberService, that.subscriberService);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(subscriberService);
+    }
+
+    @Override
+    public String toString() {
+        return "DBEventSubscriber{" + "subscriberService='" + subscriberService + '\'' + '}';
+    }
+}
diff --git a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventType.java
similarity index 59%
copy from airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/DBEventType.java
index 705d082370..a7361c44f8 100644
--- a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DBEventType.java
@@ -17,18 +17,33 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.server;
+package org.apache.airavata.common.model;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/**
+ * Domain enum: DBEventType
+ */
+public enum DBEventType {
+    PUBLISHER(0),
+    SUBSCRIBER(1);
+
+    private final int value;
 
-public class TestAiravataServiceServer {
+    DBEventType(int value) {
+        this.value = value;
+    }
 
-    private static final Logger logger = LoggerFactory.getLogger(TestAiravataServiceServer.class);
+    public int getValue() {
+        return value;
+    }
 
-    public static void main(String[] args) {
-        throw new UnsupportedOperationException(
-                "AiravataServiceServer must be used within a Spring application context. "
-                        + "Use Spring Boot application or provide dependencies manually via constructor.");
+    public static DBEventType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return PUBLISHER;
+            case 1:
+                return SUBSCRIBER;
+            default:
+                return null;
+        }
     }
 }
diff --git a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DMType.java
similarity index 59%
copy from airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/DMType.java
index 705d082370..5c0906202b 100644
--- a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DMType.java
@@ -17,18 +17,33 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.server;
+package org.apache.airavata.common.model;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/**
+ * Domain enum: DMType
+ */
+public enum DMType {
+    COMPUTE_RESOURCE(0),
+    STORAGE_RESOURCE(1);
+
+    private final int value;
 
-public class TestAiravataServiceServer {
+    DMType(int value) {
+        this.value = value;
+    }
 
-    private static final Logger logger = LoggerFactory.getLogger(TestAiravataServiceServer.class);
+    public int getValue() {
+        return value;
+    }
 
-    public static void main(String[] args) {
-        throw new UnsupportedOperationException(
-                "AiravataServiceServer must be used within a Spring application context. "
-                        + "Use Spring Boot application or provide dependencies manually via constructor.");
+    public static DMType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return COMPUTE_RESOURCE;
+            case 1:
+                return STORAGE_RESOURCE;
+            default:
+                return null;
+        }
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/DataBlock.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DataBlock.java
new file mode 100644
index 0000000000..4c905064ca
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DataBlock.java
@@ -0,0 +1,98 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: DataBlock
+ */
+public class DataBlock {
+    private String id;
+    private String value;
+    private DataType type;
+    private long createdAt;
+    private long updatedAt;
+
+    public DataBlock() {}
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public DataType getType() {
+        return type;
+    }
+
+    public void setType(DataType type) {
+        this.type = type;
+    }
+
+    public long getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(long createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public long getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public void setUpdatedAt(long updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DataBlock that = (DataBlock) o;
+        return Objects.equals(id, that.id)
+                && Objects.equals(value, that.value)
+                && Objects.equals(type, that.type)
+                && Objects.equals(createdAt, that.createdAt)
+                && Objects.equals(updatedAt, that.updatedAt);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, value, type, createdAt, updatedAt);
+    }
+
+    @Override
+    public String toString() {
+        return "DataBlock{" + "id=" + id + ", value=" + value + ", type=" + type + ", createdAt=" + createdAt
+                + ", updatedAt=" + updatedAt + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/DataMovementInterface.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DataMovementInterface.java
new file mode 100644
index 0000000000..dcf7efee25
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DataMovementInterface.java
@@ -0,0 +1,116 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: DataMovementInterface
+ */
+public class DataMovementInterface {
+    private String dataMovementInterfaceId;
+    private DataMovementProtocol dataMovementProtocol;
+    private int priorityOrder;
+    private long creationTime;
+    private long updateTime;
+    private String storageResourceId;
+
+    public DataMovementInterface() {}
+
+    public String getDataMovementInterfaceId() {
+        return dataMovementInterfaceId;
+    }
+
+    public void setDataMovementInterfaceId(String dataMovementInterfaceId) {
+        this.dataMovementInterfaceId = dataMovementInterfaceId;
+    }
+
+    public DataMovementProtocol getDataMovementProtocol() {
+        return dataMovementProtocol;
+    }
+
+    public void setDataMovementProtocol(DataMovementProtocol dataMovementProtocol) {
+        this.dataMovementProtocol = dataMovementProtocol;
+    }
+
+    public int getPriorityOrder() {
+        return priorityOrder;
+    }
+
+    public void setPriorityOrder(int priorityOrder) {
+        this.priorityOrder = priorityOrder;
+    }
+
+    public long getCreationTime() {
+        return creationTime;
+    }
+
+    public void setCreationTime(long creationTime) {
+        this.creationTime = creationTime;
+    }
+
+    public long getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(long updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public String getStorageResourceId() {
+        return storageResourceId;
+    }
+
+    public void setStorageResourceId(String storageResourceId) {
+        this.storageResourceId = storageResourceId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DataMovementInterface that = (DataMovementInterface) o;
+        return Objects.equals(dataMovementInterfaceId, that.dataMovementInterfaceId)
+                && Objects.equals(dataMovementProtocol, that.dataMovementProtocol)
+                && Objects.equals(priorityOrder, that.priorityOrder)
+                && Objects.equals(creationTime, that.creationTime)
+                && Objects.equals(updateTime, that.updateTime)
+                && Objects.equals(storageResourceId, that.storageResourceId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                dataMovementInterfaceId,
+                dataMovementProtocol,
+                priorityOrder,
+                creationTime,
+                updateTime,
+                storageResourceId);
+    }
+
+    @Override
+    public String toString() {
+        return "DataMovementInterface{" + "dataMovementInterfaceId=" + dataMovementInterfaceId
+                + ", dataMovementProtocol=" + dataMovementProtocol + ", priorityOrder=" + priorityOrder
+                + ", creationTime=" + creationTime + ", updateTime=" + updateTime + ", storageResourceId="
+                + storageResourceId + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/SharingRegistryConstants.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DataMovementProtocol.java
similarity index 51%
copy from airavata-api/src/main/java/org/apache/airavata/api/thrift/util/SharingRegistryConstants.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/DataMovementProtocol.java
index 5ab9f782a8..a23890d521 100644
--- a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/SharingRegistryConstants.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DataMovementProtocol.java
@@ -17,26 +17,42 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.util;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.airavata.common.utils.DBEventService;
+package org.apache.airavata.common.model;
 
 /**
- * Created by Ajinkya on 3/28/17.
+ * Domain enum: DataMovementProtocol
  */
-public class SharingRegistryConstants {
-    /**
-     * List of publishers in which sharing service is interested.
-     * Add publishers as required
-     */
-    public static final List<String> PUBLISHERS = new ArrayList<String>() {
-        {
-            add(DBEventService.USER_PROFILE.toString());
-            add(DBEventService.TENANT.toString());
-            add(DBEventService.REGISTRY.toString());
-            add(DBEventService.IAM_ADMIN.toString());
+public enum DataMovementProtocol {
+    LOCAL(0),
+    SCP(1),
+    SFTP(2),
+    GridFTP(3),
+    UNICORE_STORAGE_SERVICE(4);
+
+    private final int value;
+
+    DataMovementProtocol(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static DataMovementProtocol findByValue(int value) {
+        switch (value) {
+            case 0:
+                return LOCAL;
+            case 1:
+                return SCP;
+            case 2:
+                return SFTP;
+            case 3:
+                return GridFTP;
+            case 4:
+                return UNICORE_STORAGE_SERVICE;
+            default:
+                return null;
         }
-    };
+    }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/DataProductModel.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DataProductModel.java
new file mode 100644
index 0000000000..d05e555aab
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DataProductModel.java
@@ -0,0 +1,193 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Domain model: DataProductModel
+ */
+public class DataProductModel {
+    private String productUri;
+    private String gatewayId;
+    private String parentProductUri;
+    private String productName;
+    private String productDescription;
+    private String ownerName;
+    private DataProductType dataProductType;
+    private int productSize;
+    private long creationTime;
+    private long lastModifiedTime;
+    private java.util.Map<java.lang.String, java.lang.String> productMetadata;
+    private List<DataReplicaLocationModel> replicaLocations;
+
+    public DataProductModel() {}
+
+    public String getProductUri() {
+        return productUri;
+    }
+
+    public void setProductUri(String productUri) {
+        this.productUri = productUri;
+    }
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public void setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+    }
+
+    public String getParentProductUri() {
+        return parentProductUri;
+    }
+
+    public void setParentProductUri(String parentProductUri) {
+        this.parentProductUri = parentProductUri;
+    }
+
+    public String getProductName() {
+        return productName;
+    }
+
+    public void setProductName(String productName) {
+        this.productName = productName;
+    }
+
+    public String getProductDescription() {
+        return productDescription;
+    }
+
+    public void setProductDescription(String productDescription) {
+        this.productDescription = productDescription;
+    }
+
+    public String getOwnerName() {
+        return ownerName;
+    }
+
+    public void setOwnerName(String ownerName) {
+        this.ownerName = ownerName;
+    }
+
+    public DataProductType getDataProductType() {
+        return dataProductType;
+    }
+
+    public void setDataProductType(DataProductType dataProductType) {
+        this.dataProductType = dataProductType;
+    }
+
+    public int getProductSize() {
+        return productSize;
+    }
+
+    public void setProductSize(int productSize) {
+        this.productSize = productSize;
+    }
+
+    public long getCreationTime() {
+        return creationTime;
+    }
+
+    public void setCreationTime(long creationTime) {
+        this.creationTime = creationTime;
+    }
+
+    public long getLastModifiedTime() {
+        return lastModifiedTime;
+    }
+
+    public void setLastModifiedTime(long lastModifiedTime) {
+        this.lastModifiedTime = lastModifiedTime;
+    }
+
+    public Map<String, String> getProductMetadata() {
+        if (productMetadata == null) {
+            productMetadata = new HashMap<>();
+        }
+        return productMetadata;
+    }
+
+    public void setProductMetadata(Map<String, String> productMetadata) {
+        this.productMetadata = productMetadata;
+    }
+
+    public List<DataReplicaLocationModel> getReplicaLocations() {
+        if (replicaLocations == null) {
+            replicaLocations = new ArrayList<>();
+        }
+        return replicaLocations;
+    }
+
+    public void setReplicaLocations(List<DataReplicaLocationModel> replicaLocations) {
+        this.replicaLocations = replicaLocations;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DataProductModel that = (DataProductModel) o;
+        return Objects.equals(productUri, that.productUri)
+                && Objects.equals(gatewayId, that.gatewayId)
+                && Objects.equals(parentProductUri, that.parentProductUri)
+                && Objects.equals(productName, that.productName)
+                && Objects.equals(productDescription, that.productDescription)
+                && Objects.equals(ownerName, that.ownerName)
+                && Objects.equals(dataProductType, that.dataProductType)
+                && Objects.equals(productSize, that.productSize)
+                && Objects.equals(creationTime, that.creationTime)
+                && Objects.equals(lastModifiedTime, that.lastModifiedTime)
+                && Objects.equals(productMetadata, that.productMetadata)
+                && Objects.equals(replicaLocations, that.replicaLocations);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                productUri,
+                gatewayId,
+                parentProductUri,
+                productName,
+                productDescription,
+                ownerName,
+                dataProductType,
+                productSize,
+                creationTime,
+                lastModifiedTime,
+                productMetadata,
+                replicaLocations);
+    }
+
+    @Override
+    public String toString() {
+        return "DataProductModel{" + "productUri=" + productUri + ", gatewayId=" + gatewayId + ", parentProductUri="
+                + parentProductUri + ", productName=" + productName + ", productDescription=" + productDescription
+                + ", ownerName=" + ownerName + ", dataProductType=" + dataProductType + ", productSize=" + productSize
+                + ", creationTime=" + creationTime + ", lastModifiedTime=" + lastModifiedTime + ", productMetadata="
+                + productMetadata + ", replicaLocations=" + replicaLocations + "}";
+    }
+}
diff --git a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DataProductType.java
similarity index 59%
copy from airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/DataProductType.java
index 705d082370..6601616f33 100644
--- a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DataProductType.java
@@ -17,18 +17,33 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.server;
+package org.apache.airavata.common.model;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/**
+ * Domain enum: DataProductType
+ */
+public enum DataProductType {
+    FILE(0),
+    COLLECTION(1);
+
+    private final int value;
 
-public class TestAiravataServiceServer {
+    DataProductType(int value) {
+        this.value = value;
+    }
 
-    private static final Logger logger = LoggerFactory.getLogger(TestAiravataServiceServer.class);
+    public int getValue() {
+        return value;
+    }
 
-    public static void main(String[] args) {
-        throw new UnsupportedOperationException(
-                "AiravataServiceServer must be used within a Spring application context. "
-                        + "Use Spring Boot application or provide dependencies manually via constructor.");
+    public static DataProductType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return FILE;
+            case 1:
+                return COLLECTION;
+            default:
+                return null;
+        }
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/registry/entities/replicacatalog/DataReplicaLocationEntity.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DataReplicaLocationModel.java
similarity index 50%
copy from airavata-api/src/main/java/org/apache/airavata/registry/entities/replicacatalog/DataReplicaLocationEntity.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/DataReplicaLocationModel.java
index 1213542935..1bef1115be 100644
--- a/airavata-api/src/main/java/org/apache/airavata/registry/entities/replicacatalog/DataReplicaLocationEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DataReplicaLocationModel.java
@@ -17,81 +17,28 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.registry.entities.replicacatalog;
-
-import jakarta.persistence.CollectionTable;
-import jakarta.persistence.Column;
-import jakarta.persistence.ElementCollection;
-import jakarta.persistence.Entity;
-import jakarta.persistence.EnumType;
-import jakarta.persistence.Enumerated;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.Lob;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.MapKeyColumn;
-import jakarta.persistence.Table;
-import java.io.Serializable;
-import java.sql.Timestamp;
-import java.util.Map;
-import org.apache.airavata.common.model.ReplicaLocationCategory;
-import org.apache.airavata.common.model.ReplicaPersistentType;
+package org.apache.airavata.common.model;
+
+import java.util.Objects;
 
 /**
- * The persistent class for the data_replica_location database table.
+ * Domain model: DataReplicaLocationModel
  */
-@Entity
-@Table(name = "DATA_REPLICA_LOCATION")
-public class DataReplicaLocationEntity implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    @Id
-    @Column(name = "REPLICA_ID", nullable = false)
+public class DataReplicaLocationModel {
     private String replicaId;
-
-    @Column(name = "PRODUCT_URI", nullable = false)
     private String productUri;
-
-    @Lob
-    @Column(name = "REPLICA_NAME")
     private String replicaName;
-
-    @Column(name = "REPLICA_DESCRIPTION")
     private String replicaDescription;
-
-    @Column(name = "STORAGE_RESOURCE_ID")
-    private String storageResourceId;
-
-    @Column(name = "FILE_PATH")
-    private String filePath;
-
-    @Column(name = "CREATION_TIME")
-    private Timestamp creationTime;
-
-    @Column(name = "LAST_MODIFIED_TIME")
-    private Timestamp lastModifiedTime;
-
-    @Column(name = "VALID_UNTIL_TIME")
-    private Timestamp validUntilTime;
-
-    @Column(name = "REPLICA_LOCATION_CATEGORY")
-    @Enumerated(EnumType.STRING)
+    private long creationTime;
+    private long lastModifiedTime;
+    private long validUntilTime;
     private ReplicaLocationCategory replicaLocationCategory;
-
-    @Column(name = "REPLICA_PERSISTENT_TYPE")
-    @Enumerated(EnumType.STRING)
     private ReplicaPersistentType replicaPersistentType;
+    private String storageResourceId;
+    private String filePath;
+    private java.util.Map<java.lang.String, java.lang.String> replicaMetadata;
 
-    @ElementCollection(fetch = FetchType.EAGER)
-    @CollectionTable(name = "DATA_REPLICA_METADATA", joinColumns = @JoinColumn(name = "REPLICA_ID"))
-    @MapKeyColumn(name = "METADATA_KEY")
-    @Column(name = "METADATA_VALUE")
-    private Map<String, String> replicaMetadata;
-
-    @ManyToOne(targetEntity = DataProductEntity.class)
-    @JoinColumn(name = "PRODUCT_URI", nullable = false, updatable = false)
-    private DataProductEntity dataProduct;
+    public DataReplicaLocationModel() {}
 
     public String getReplicaId() {
         return replicaId;
@@ -125,43 +72,27 @@ public class DataReplicaLocationEntity implements Serializable {
         this.replicaDescription = replicaDescription;
     }
 
-    public String getStorageResourceId() {
-        return storageResourceId;
-    }
-
-    public void setStorageResourceId(String storageResourceId) {
-        this.storageResourceId = storageResourceId;
-    }
-
-    public String getFilePath() {
-        return filePath;
-    }
-
-    public void setFilePath(String filePath) {
-        this.filePath = filePath;
-    }
-
-    public Timestamp getCreationTime() {
+    public long getCreationTime() {
         return creationTime;
     }
 
-    public void setCreationTime(Timestamp creationTime) {
+    public void setCreationTime(long creationTime) {
         this.creationTime = creationTime;
     }
 
-    public Timestamp getLastModifiedTime() {
+    public long getLastModifiedTime() {
         return lastModifiedTime;
     }
 
-    public void setLastModifiedTime(Timestamp lastModifiedTime) {
+    public void setLastModifiedTime(long lastModifiedTime) {
         this.lastModifiedTime = lastModifiedTime;
     }
 
-    public Timestamp getValidUntilTime() {
+    public long getValidUntilTime() {
         return validUntilTime;
     }
 
-    public void setValidUntilTime(Timestamp validUntilTime) {
+    public void setValidUntilTime(long validUntilTime) {
         this.validUntilTime = validUntilTime;
     }
 
@@ -181,19 +112,73 @@ public class DataReplicaLocationEntity implements Serializable {
         this.replicaPersistentType = replicaPersistentType;
     }
 
-    public Map<String, String> getReplicaMetadata() {
-        return replicaMetadata;
+    public String getStorageResourceId() {
+        return storageResourceId;
     }
 
-    public void setReplicaMetadata(Map<String, String> replicaMetadata) {
-        this.replicaMetadata = replicaMetadata;
+    public void setStorageResourceId(String storageResourceId) {
+        this.storageResourceId = storageResourceId;
     }
 
-    public DataProductEntity getDataProduct() {
-        return dataProduct;
+    public String getFilePath() {
+        return filePath;
+    }
+
+    public void setFilePath(String filePath) {
+        this.filePath = filePath;
+    }
+
+    public java.util.Map<java.lang.String, java.lang.String> getReplicaMetadata() {
+        return replicaMetadata;
+    }
+
+    public void setReplicaMetadata(java.util.Map<java.lang.String, java.lang.String> replicaMetadata) {
+        this.replicaMetadata = replicaMetadata;
     }
 
-    public void setDataProduct(DataProductEntity dataProduct) {
-        this.dataProduct = dataProduct;
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DataReplicaLocationModel that = (DataReplicaLocationModel) o;
+        return Objects.equals(replicaId, that.replicaId)
+                && Objects.equals(productUri, that.productUri)
+                && Objects.equals(replicaName, that.replicaName)
+                && Objects.equals(replicaDescription, that.replicaDescription)
+                && Objects.equals(creationTime, that.creationTime)
+                && Objects.equals(lastModifiedTime, that.lastModifiedTime)
+                && Objects.equals(validUntilTime, that.validUntilTime)
+                && Objects.equals(replicaLocationCategory, that.replicaLocationCategory)
+                && Objects.equals(replicaPersistentType, that.replicaPersistentType)
+                && Objects.equals(storageResourceId, that.storageResourceId)
+                && Objects.equals(filePath, that.filePath)
+                && Objects.equals(replicaMetadata, that.replicaMetadata);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                replicaId,
+                productUri,
+                replicaName,
+                replicaDescription,
+                creationTime,
+                lastModifiedTime,
+                validUntilTime,
+                replicaLocationCategory,
+                replicaPersistentType,
+                storageResourceId,
+                filePath,
+                replicaMetadata);
+    }
+
+    @Override
+    public String toString() {
+        return "DataReplicaLocationModel{" + "replicaId=" + replicaId + ", productUri=" + productUri + ", replicaName="
+                + replicaName + ", replicaDescription=" + replicaDescription + ", creationTime=" + creationTime
+                + ", lastModifiedTime=" + lastModifiedTime + ", validUntilTime=" + validUntilTime
+                + ", replicaLocationCategory=" + replicaLocationCategory + ", replicaPersistentType="
+                + replicaPersistentType + ", storageResourceId=" + storageResourceId + ", filePath=" + filePath
+                + ", replicaMetadata=" + replicaMetadata + "}";
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DataStageType.java
similarity index 57%
copy from airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/DataStageType.java
index c7599da358..dbf0b359f5 100644
--- a/airavata-api/src/main/java/org/apache/airavata/config/DozerMapperConfig.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DataStageType.java
@@ -17,23 +17,36 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.config;
-
-import com.github.dozermapper.core.DozerBeanMapperBuilder;
-import com.github.dozermapper.core.Mapper;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+package org.apache.airavata.common.model;
 
 /**
- * Configuration for Dozer mapper bean.
- * Replaces the three ObjectMapperSingleton classes with a single Spring-managed bean.
+ * Domain enum: DataStageType
  */
-@Configuration
-public class DozerMapperConfig {
-    @Bean
-    public Mapper dozerMapper() {
-        return DozerBeanMapperBuilder.create()
-                .withMappingFiles("dozer_mapping.xml")
-                .build();
+public enum DataStageType {
+    INPUT(0),
+    OUPUT(1),
+    ARCHIVE_OUTPUT(2);
+
+    private final int value;
+
+    DataStageType(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static DataStageType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return INPUT;
+            case 1:
+                return OUPUT;
+            case 2:
+                return ARCHIVE_OUTPUT;
+            default:
+                return null;
+        }
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/DataStagingTaskModel.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DataStagingTaskModel.java
new file mode 100644
index 0000000000..e171f3f4a5
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DataStagingTaskModel.java
@@ -0,0 +1,138 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: DataStagingTaskModel
+ */
+public class DataStagingTaskModel {
+    private String source;
+    private String destination;
+    private DataStageType type;
+    private long transferStartTime;
+    private long transferEndTime;
+    private String transferRate;
+    private InputDataObjectType processInput;
+    private OutputDataObjectType processOutput;
+
+    public DataStagingTaskModel() {}
+
+    public String getSource() {
+        return source;
+    }
+
+    public void setSource(String source) {
+        this.source = source;
+    }
+
+    public String getDestination() {
+        return destination;
+    }
+
+    public void setDestination(String destination) {
+        this.destination = destination;
+    }
+
+    public DataStageType getType() {
+        return type;
+    }
+
+    public void setType(DataStageType type) {
+        this.type = type;
+    }
+
+    public long getTransferStartTime() {
+        return transferStartTime;
+    }
+
+    public void setTransferStartTime(long transferStartTime) {
+        this.transferStartTime = transferStartTime;
+    }
+
+    public long getTransferEndTime() {
+        return transferEndTime;
+    }
+
+    public void setTransferEndTime(long transferEndTime) {
+        this.transferEndTime = transferEndTime;
+    }
+
+    public String getTransferRate() {
+        return transferRate;
+    }
+
+    public void setTransferRate(String transferRate) {
+        this.transferRate = transferRate;
+    }
+
+    public InputDataObjectType getProcessInput() {
+        return processInput;
+    }
+
+    public void setProcessInput(InputDataObjectType processInput) {
+        this.processInput = processInput;
+    }
+
+    public OutputDataObjectType getProcessOutput() {
+        return processOutput;
+    }
+
+    public void setProcessOutput(OutputDataObjectType processOutput) {
+        this.processOutput = processOutput;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DataStagingTaskModel that = (DataStagingTaskModel) o;
+        return Objects.equals(source, that.source)
+                && Objects.equals(destination, that.destination)
+                && Objects.equals(type, that.type)
+                && Objects.equals(transferStartTime, that.transferStartTime)
+                && Objects.equals(transferEndTime, that.transferEndTime)
+                && Objects.equals(transferRate, that.transferRate)
+                && Objects.equals(processInput, that.processInput)
+                && Objects.equals(processOutput, that.processOutput);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                source,
+                destination,
+                type,
+                transferStartTime,
+                transferEndTime,
+                transferRate,
+                processInput,
+                processOutput);
+    }
+
+    @Override
+    public String toString() {
+        return "DataStagingTaskModel{" + "source=" + source + ", destination=" + destination + ", type=" + type
+                + ", transferStartTime=" + transferStartTime + ", transferEndTime=" + transferEndTime
+                + ", transferRate=" + transferRate + ", processInput=" + processInput + ", processOutput="
+                + processOutput + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/DataType.java b/airavata-api/src/main/java/org/apache/airavata/common/model/DataType.java
new file mode 100644
index 0000000000..a77375912c
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/DataType.java
@@ -0,0 +1,64 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+/**
+ * Domain enum: DataType
+ */
+public enum DataType {
+    STRING(0),
+    INTEGER(1),
+    FLOAT(2),
+    URI(3),
+    URI_COLLECTION(4),
+    STDOUT(5),
+    STDERR(6);
+
+    private final int value;
+
+    DataType(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static DataType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return STRING;
+            case 1:
+                return INTEGER;
+            case 2:
+                return FLOAT;
+            case 3:
+                return URI;
+            case 4:
+                return URI_COLLECTION;
+            case 5:
+                return STDOUT;
+            case 6:
+                return STDERR;
+            default:
+                return null;
+        }
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/EdgeModel.java b/airavata-api/src/main/java/org/apache/airavata/common/model/EdgeModel.java
new file mode 100644
index 0000000000..1e5aff2c66
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/EdgeModel.java
@@ -0,0 +1,88 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: EdgeModel
+ */
+public class EdgeModel {
+    private String edgeId;
+    private String name;
+    private ComponentStatus status;
+    private String description;
+
+    public EdgeModel() {}
+
+    public String getEdgeId() {
+        return edgeId;
+    }
+
+    public void setEdgeId(String edgeId) {
+        this.edgeId = edgeId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public ComponentStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(ComponentStatus status) {
+        this.status = status;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        EdgeModel that = (EdgeModel) o;
+        return Objects.equals(edgeId, that.edgeId)
+                && Objects.equals(name, that.name)
+                && Objects.equals(status, that.status)
+                && Objects.equals(description, that.description);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(edgeId, name, status, description);
+    }
+
+    @Override
+    public String toString() {
+        return "EdgeModel{" + "edgeId=" + edgeId + ", name=" + name + ", status=" + status + ", description="
+                + description + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/EntityType.java b/airavata-api/src/main/java/org/apache/airavata/common/model/EntityType.java
new file mode 100644
index 0000000000..6ca8b98a45
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/EntityType.java
@@ -0,0 +1,67 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+/**
+ * Domain enum: EntityType
+ */
+public enum EntityType {
+    USER_PROFILE(0),
+    TENANT(1),
+    GROUP(2),
+    PROJECT(3),
+    EXPERIMENT(4),
+    APPLICATION(5),
+    SHARING(6),
+    REGISTRY(7);
+
+    private final int value;
+
+    EntityType(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static EntityType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return USER_PROFILE;
+            case 1:
+                return TENANT;
+            case 2:
+                return GROUP;
+            case 3:
+                return PROJECT;
+            case 4:
+                return EXPERIMENT;
+            case 5:
+                return APPLICATION;
+            case 6:
+                return SHARING;
+            case 7:
+                return REGISTRY;
+            default:
+                return null;
+        }
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/EnvironmentSetupTaskModel.java b/airavata-api/src/main/java/org/apache/airavata/common/model/EnvironmentSetupTaskModel.java
new file mode 100644
index 0000000000..b9c48dc81c
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/EnvironmentSetupTaskModel.java
@@ -0,0 +1,66 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: EnvironmentSetupTaskModel
+ */
+public class EnvironmentSetupTaskModel {
+    private String location;
+    private SecurityProtocol protocol;
+
+    public EnvironmentSetupTaskModel() {}
+
+    public String getLocation() {
+        return location;
+    }
+
+    public void setLocation(String location) {
+        this.location = location;
+    }
+
+    public SecurityProtocol getProtocol() {
+        return protocol;
+    }
+
+    public void setProtocol(SecurityProtocol protocol) {
+        this.protocol = protocol;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        EnvironmentSetupTaskModel that = (EnvironmentSetupTaskModel) o;
+        return Objects.equals(location, that.location) && Objects.equals(protocol, that.protocol);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(location, protocol);
+    }
+
+    @Override
+    public String toString() {
+        return "EnvironmentSetupTaskModel{" + "location=" + location + ", protocol=" + protocol + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/EnvironmentSpecificPreferences.java b/airavata-api/src/main/java/org/apache/airavata/common/model/EnvironmentSpecificPreferences.java
new file mode 100644
index 0000000000..e59160df8a
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/EnvironmentSpecificPreferences.java
@@ -0,0 +1,101 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: EnvironmentSpecificPreferences
+ * Union type that can be either SlurmComputeResourcePreference or AwsComputeResourcePreference.
+ */
+public class EnvironmentSpecificPreferences {
+    private SlurmComputeResourcePreference slurm;
+    private AwsComputeResourcePreference aws;
+
+    public EnvironmentSpecificPreferences() {}
+
+    public SlurmComputeResourcePreference getSlurm() {
+        return slurm;
+    }
+
+    public void setSlurm(SlurmComputeResourcePreference slurm) {
+        this.slurm = slurm;
+        this.aws = null; // Clear aws when setting slurm
+    }
+
+    public AwsComputeResourcePreference getAws() {
+        return aws;
+    }
+
+    public void setAws(AwsComputeResourcePreference aws) {
+        this.aws = aws;
+        this.slurm = null; // Clear slurm when setting aws
+    }
+
+    /**
+     * Static factory method to create a slurm preference.
+     */
+    public static EnvironmentSpecificPreferences slurm(SlurmComputeResourcePreference slurm) {
+        EnvironmentSpecificPreferences prefs = new EnvironmentSpecificPreferences();
+        prefs.setSlurm(slurm);
+        return prefs;
+    }
+
+    /**
+     * Static factory method to create an aws preference.
+     */
+    public static EnvironmentSpecificPreferences aws(AwsComputeResourcePreference aws) {
+        EnvironmentSpecificPreferences prefs = new EnvironmentSpecificPreferences();
+        prefs.setAws(aws);
+        return prefs;
+    }
+
+    public boolean isSlurm() {
+        return slurm != null;
+    }
+
+    public boolean isAws() {
+        return aws != null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        EnvironmentSpecificPreferences that = (EnvironmentSpecificPreferences) o;
+        return Objects.equals(slurm, that.slurm) && Objects.equals(aws, that.aws);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(slurm, aws);
+    }
+
+    @Override
+    public String toString() {
+        if (slurm != null) {
+            return "EnvironmentSpecificPreferences{slurm=" + slurm + "}";
+        } else if (aws != null) {
+            return "EnvironmentSpecificPreferences{aws=" + aws + "}";
+        } else {
+            return "EnvironmentSpecificPreferences{empty}";
+        }
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ErrorModel.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ErrorModel.java
new file mode 100644
index 0000000000..7ff2dfc4ab
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ErrorModel.java
@@ -0,0 +1,116 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: ErrorModel
+ */
+public class ErrorModel {
+    private String errorId;
+    private long creationTime;
+    private String actualErrorMessage;
+    private String userFriendlyMessage;
+    private boolean transientOrPersistent;
+    private List<String> rootCauseErrorIdList;
+
+    public ErrorModel() {}
+
+    public String getErrorId() {
+        return errorId;
+    }
+
+    public void setErrorId(String errorId) {
+        this.errorId = errorId;
+    }
+
+    public long getCreationTime() {
+        return creationTime;
+    }
+
+    public void setCreationTime(long creationTime) {
+        this.creationTime = creationTime;
+    }
+
+    public String getActualErrorMessage() {
+        return actualErrorMessage;
+    }
+
+    public void setActualErrorMessage(String actualErrorMessage) {
+        this.actualErrorMessage = actualErrorMessage;
+    }
+
+    public String getUserFriendlyMessage() {
+        return userFriendlyMessage;
+    }
+
+    public void setUserFriendlyMessage(String userFriendlyMessage) {
+        this.userFriendlyMessage = userFriendlyMessage;
+    }
+
+    public boolean getTransientOrPersistent() {
+        return transientOrPersistent;
+    }
+
+    public void setTransientOrPersistent(boolean transientOrPersistent) {
+        this.transientOrPersistent = transientOrPersistent;
+    }
+
+    public List<String> getRootCauseErrorIdList() {
+        return rootCauseErrorIdList;
+    }
+
+    public void setRootCauseErrorIdList(List<String> rootCauseErrorIdList) {
+        this.rootCauseErrorIdList = rootCauseErrorIdList;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ErrorModel that = (ErrorModel) o;
+        return Objects.equals(errorId, that.errorId)
+                && Objects.equals(creationTime, that.creationTime)
+                && Objects.equals(actualErrorMessage, that.actualErrorMessage)
+                && Objects.equals(userFriendlyMessage, that.userFriendlyMessage)
+                && Objects.equals(transientOrPersistent, that.transientOrPersistent)
+                && Objects.equals(rootCauseErrorIdList, that.rootCauseErrorIdList);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                errorId,
+                creationTime,
+                actualErrorMessage,
+                userFriendlyMessage,
+                transientOrPersistent,
+                rootCauseErrorIdList);
+    }
+
+    @Override
+    public String toString() {
+        return "ErrorModel{" + "errorId=" + errorId + ", creationTime=" + creationTime + ", actualErrorMessage="
+                + actualErrorMessage + ", userFriendlyMessage=" + userFriendlyMessage + ", transientOrPersistent="
+                + transientOrPersistent + ", rootCauseErrorIdList=" + rootCauseErrorIdList + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/SharingRegistryConstants.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentCleanupStrategy.java
similarity index 52%
copy from airavata-api/src/main/java/org/apache/airavata/api/thrift/util/SharingRegistryConstants.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentCleanupStrategy.java
index 5ab9f782a8..29817c0c2c 100644
--- a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/SharingRegistryConstants.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentCleanupStrategy.java
@@ -17,26 +17,39 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.util;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.airavata.common.utils.DBEventService;
+package org.apache.airavata.common.model;
 
 /**
- * Created by Ajinkya on 3/28/17.
+ * Domain enum: ExperimentCleanupStrategy
  */
-public class SharingRegistryConstants {
-    /**
-     * List of publishers in which sharing service is interested.
-     * Add publishers as required
-     */
-    public static final List<String> PUBLISHERS = new ArrayList<String>() {
-        {
-            add(DBEventService.USER_PROFILE.toString());
-            add(DBEventService.TENANT.toString());
-            add(DBEventService.REGISTRY.toString());
-            add(DBEventService.IAM_ADMIN.toString());
+public enum ExperimentCleanupStrategy {
+    NONE(0),
+    ALWAYS(1),
+    ONLY_COMPLETED(2),
+    ONLY_FAILED(3);
+
+    private final int value;
+
+    ExperimentCleanupStrategy(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static ExperimentCleanupStrategy findByValue(int value) {
+        switch (value) {
+            case 0:
+                return NONE;
+            case 1:
+                return ALWAYS;
+            case 2:
+                return ONLY_COMPLETED;
+            case 3:
+                return ONLY_FAILED;
+            default:
+                return null;
         }
-    };
+    }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentIntermediateOutputsEvent.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentIntermediateOutputsEvent.java
new file mode 100644
index 0000000000..fcc20ec7f1
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentIntermediateOutputsEvent.java
@@ -0,0 +1,85 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: ExperimentIntermediateOutputsEvent
+ */
+public class ExperimentIntermediateOutputsEvent extends MessagingEvent {
+    private String experimentId;
+    private String gatewayId;
+    private List<String> outputNames;
+
+    public ExperimentIntermediateOutputsEvent() {}
+
+    public ExperimentIntermediateOutputsEvent(String experimentId, String gatewayId, List<String> outputNames) {
+        this.experimentId = experimentId;
+        this.gatewayId = gatewayId;
+        this.outputNames = outputNames;
+    }
+
+    public String getExperimentId() {
+        return experimentId;
+    }
+
+    public void setExperimentId(String experimentId) {
+        this.experimentId = experimentId;
+    }
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public void setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+    }
+
+    public List<String> getOutputNames() {
+        return outputNames;
+    }
+
+    public void setOutputNames(List<String> outputNames) {
+        this.outputNames = outputNames;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ExperimentIntermediateOutputsEvent that = (ExperimentIntermediateOutputsEvent) o;
+        return Objects.equals(experimentId, that.experimentId)
+                && Objects.equals(gatewayId, that.gatewayId)
+                && Objects.equals(outputNames, that.outputNames);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(experimentId, gatewayId, outputNames);
+    }
+
+    @Override
+    public String toString() {
+        return "ExperimentIntermediateOutputsEvent{" + "experimentId=" + experimentId + ", gatewayId=" + gatewayId
+                + ", outputNames=" + outputNames + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentModel.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentModel.java
new file mode 100644
index 0000000000..55fcc32ccd
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentModel.java
@@ -0,0 +1,287 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: ExperimentModel
+ */
+public class ExperimentModel {
+    private String experimentId;
+    private String projectId;
+    private String gatewayId;
+    private ExperimentType experimentType;
+    private String userName;
+    private String experimentName;
+    private long creationTime;
+    private String description;
+    private String executionId;
+    private String gatewayExecutionId;
+    private String gatewayInstanceId;
+    private boolean enableEmailNotification;
+    private List<String> emailAddresses;
+    private UserConfigurationDataModel userConfigurationData;
+    private List<InputDataObjectType> experimentInputs;
+    private List<OutputDataObjectType> experimentOutputs;
+    private List<ExperimentStatus> experimentStatus;
+    private List<ErrorModel> errors;
+    private List<ProcessModel> processes;
+    private AiravataWorkflow workflow;
+    private ExperimentCleanupStrategy cleanUpStrategy;
+
+    public ExperimentModel() {}
+
+    public String getExperimentId() {
+        return experimentId;
+    }
+
+    public void setExperimentId(String experimentId) {
+        this.experimentId = experimentId;
+    }
+
+    public String getProjectId() {
+        return projectId;
+    }
+
+    public void setProjectId(String projectId) {
+        this.projectId = projectId;
+    }
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public void setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+    }
+
+    public ExperimentType getExperimentType() {
+        return experimentType;
+    }
+
+    public void setExperimentType(ExperimentType experimentType) {
+        this.experimentType = experimentType;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getExperimentName() {
+        return experimentName;
+    }
+
+    public void setExperimentName(String experimentName) {
+        this.experimentName = experimentName;
+    }
+
+    public long getCreationTime() {
+        return creationTime;
+    }
+
+    public void setCreationTime(long creationTime) {
+        this.creationTime = creationTime;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getExecutionId() {
+        return executionId;
+    }
+
+    public void setExecutionId(String executionId) {
+        this.executionId = executionId;
+    }
+
+    public String getGatewayExecutionId() {
+        return gatewayExecutionId;
+    }
+
+    public void setGatewayExecutionId(String gatewayExecutionId) {
+        this.gatewayExecutionId = gatewayExecutionId;
+    }
+
+    public String getGatewayInstanceId() {
+        return gatewayInstanceId;
+    }
+
+    public void setGatewayInstanceId(String gatewayInstanceId) {
+        this.gatewayInstanceId = gatewayInstanceId;
+    }
+
+    public boolean getEnableEmailNotification() {
+        return enableEmailNotification;
+    }
+
+    public void setEnableEmailNotification(boolean enableEmailNotification) {
+        this.enableEmailNotification = enableEmailNotification;
+    }
+
+    public List<String> getEmailAddresses() {
+        return emailAddresses;
+    }
+
+    public void setEmailAddresses(List<String> emailAddresses) {
+        this.emailAddresses = emailAddresses;
+    }
+
+    public UserConfigurationDataModel getUserConfigurationData() {
+        return userConfigurationData;
+    }
+
+    public void setUserConfigurationData(UserConfigurationDataModel userConfigurationData) {
+        this.userConfigurationData = userConfigurationData;
+    }
+
+    public List<InputDataObjectType> getExperimentInputs() {
+        return experimentInputs;
+    }
+
+    public void setExperimentInputs(List<InputDataObjectType> experimentInputs) {
+        this.experimentInputs = experimentInputs;
+    }
+
+    public List<OutputDataObjectType> getExperimentOutputs() {
+        return experimentOutputs;
+    }
+
+    public void setExperimentOutputs(List<OutputDataObjectType> experimentOutputs) {
+        this.experimentOutputs = experimentOutputs;
+    }
+
+    public List<ExperimentStatus> getExperimentStatus() {
+        return experimentStatus;
+    }
+
+    public void setExperimentStatus(List<ExperimentStatus> experimentStatus) {
+        this.experimentStatus = experimentStatus;
+    }
+
+    public List<ErrorModel> getErrors() {
+        return errors;
+    }
+
+    public void setErrors(List<ErrorModel> errors) {
+        this.errors = errors;
+    }
+
+    public List<ProcessModel> getProcesses() {
+        return processes;
+    }
+
+    public void setProcesses(List<ProcessModel> processes) {
+        this.processes = processes;
+    }
+
+    public AiravataWorkflow getWorkflow() {
+        return workflow;
+    }
+
+    public void setWorkflow(AiravataWorkflow workflow) {
+        this.workflow = workflow;
+    }
+
+    public ExperimentCleanupStrategy getCleanUpStrategy() {
+        return cleanUpStrategy;
+    }
+
+    public void setCleanUpStrategy(ExperimentCleanupStrategy cleanUpStrategy) {
+        this.cleanUpStrategy = cleanUpStrategy;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ExperimentModel that = (ExperimentModel) o;
+        return Objects.equals(experimentId, that.experimentId)
+                && Objects.equals(projectId, that.projectId)
+                && Objects.equals(gatewayId, that.gatewayId)
+                && Objects.equals(experimentType, that.experimentType)
+                && Objects.equals(userName, that.userName)
+                && Objects.equals(experimentName, that.experimentName)
+                && Objects.equals(creationTime, that.creationTime)
+                && Objects.equals(description, that.description)
+                && Objects.equals(executionId, that.executionId)
+                && Objects.equals(gatewayExecutionId, that.gatewayExecutionId)
+                && Objects.equals(gatewayInstanceId, that.gatewayInstanceId)
+                && Objects.equals(enableEmailNotification, that.enableEmailNotification)
+                && Objects.equals(emailAddresses, that.emailAddresses)
+                && Objects.equals(userConfigurationData, that.userConfigurationData)
+                && Objects.equals(experimentInputs, that.experimentInputs)
+                && Objects.equals(experimentOutputs, that.experimentOutputs)
+                && Objects.equals(experimentStatus, that.experimentStatus)
+                && Objects.equals(errors, that.errors)
+                && Objects.equals(processes, that.processes)
+                && Objects.equals(workflow, that.workflow)
+                && Objects.equals(cleanUpStrategy, that.cleanUpStrategy);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                experimentId,
+                projectId,
+                gatewayId,
+                experimentType,
+                userName,
+                experimentName,
+                creationTime,
+                description,
+                executionId,
+                gatewayExecutionId,
+                gatewayInstanceId,
+                enableEmailNotification,
+                emailAddresses,
+                userConfigurationData,
+                experimentInputs,
+                experimentOutputs,
+                experimentStatus,
+                errors,
+                processes,
+                workflow,
+                cleanUpStrategy);
+    }
+
+    @Override
+    public String toString() {
+        return "ExperimentModel{" + "experimentId=" + experimentId + ", projectId=" + projectId + ", gatewayId="
+                + gatewayId + ", experimentType=" + experimentType + ", userName=" + userName + ", experimentName="
+                + experimentName + ", creationTime=" + creationTime + ", description=" + description + ", executionId="
+                + executionId + ", gatewayExecutionId=" + gatewayExecutionId + ", gatewayInstanceId="
+                + gatewayInstanceId + ", enableEmailNotification=" + enableEmailNotification + ", emailAddresses="
+                + emailAddresses + ", userConfigurationData=" + userConfigurationData + ", experimentInputs="
+                + experimentInputs + ", experimentOutputs=" + experimentOutputs + ", experimentStatus="
+                + experimentStatus + ", errors=" + errors + ", processes=" + processes + ", workflow=" + workflow
+                + ", cleanUpStrategy=" + cleanUpStrategy + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentSearchFields.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentSearchFields.java
new file mode 100644
index 0000000000..17adb3c49f
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentSearchFields.java
@@ -0,0 +1,70 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+/**
+ * Domain enum: ExperimentSearchFields
+ */
+public enum ExperimentSearchFields {
+    EXPERIMENT_NAME(0),
+    EXPERIMENT_DESC(1),
+    APPLICATION_ID(2),
+    FROM_DATE(3),
+    TO_DATE(4),
+    STATUS(5),
+    PROJECT_ID(6),
+    USER_NAME(7),
+    JOB_ID(8);
+
+    private final int value;
+
+    ExperimentSearchFields(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static ExperimentSearchFields findByValue(int value) {
+        switch (value) {
+            case 0:
+                return EXPERIMENT_NAME;
+            case 1:
+                return EXPERIMENT_DESC;
+            case 2:
+                return APPLICATION_ID;
+            case 3:
+                return FROM_DATE;
+            case 4:
+                return TO_DATE;
+            case 5:
+                return STATUS;
+            case 6:
+                return PROJECT_ID;
+            case 7:
+                return USER_NAME;
+            case 8:
+                return JOB_ID;
+            default:
+                return null;
+        }
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentState.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentState.java
new file mode 100644
index 0000000000..93b94abb83
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentState.java
@@ -0,0 +1,70 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+/**
+ * Domain enum: ExperimentState
+ */
+public enum ExperimentState {
+    CREATED(0),
+    VALIDATED(1),
+    SCHEDULED(2),
+    LAUNCHED(3),
+    EXECUTING(4),
+    CANCELING(5),
+    CANCELED(6),
+    COMPLETED(7),
+    FAILED(8);
+
+    private final int value;
+
+    ExperimentState(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static ExperimentState findByValue(int value) {
+        switch (value) {
+            case 0:
+                return CREATED;
+            case 1:
+                return VALIDATED;
+            case 2:
+                return SCHEDULED;
+            case 3:
+                return LAUNCHED;
+            case 4:
+                return EXECUTING;
+            case 5:
+                return CANCELING;
+            case 6:
+                return CANCELED;
+            case 7:
+                return COMPLETED;
+            case 8:
+                return FAILED;
+            default:
+                return null;
+        }
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentStatistics.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentStatistics.java
new file mode 100644
index 0000000000..9cd5886021
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentStatistics.java
@@ -0,0 +1,186 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: ExperimentStatistics
+ */
+public class ExperimentStatistics {
+    private int allExperimentCount;
+    private int completedExperimentCount;
+    private int cancelledExperimentCount;
+    private int failedExperimentCount;
+    private int createdExperimentCount;
+    private int runningExperimentCount;
+    private List<ExperimentSummaryModel> allExperiments;
+    private List<ExperimentSummaryModel> completedExperiments;
+    private List<ExperimentSummaryModel> failedExperiments;
+    private List<ExperimentSummaryModel> cancelledExperiments;
+    private List<ExperimentSummaryModel> createdExperiments;
+    private List<ExperimentSummaryModel> runningExperiments;
+
+    public ExperimentStatistics() {}
+
+    public int getAllExperimentCount() {
+        return allExperimentCount;
+    }
+
+    public void setAllExperimentCount(int allExperimentCount) {
+        this.allExperimentCount = allExperimentCount;
+    }
+
+    public int getCompletedExperimentCount() {
+        return completedExperimentCount;
+    }
+
+    public void setCompletedExperimentCount(int completedExperimentCount) {
+        this.completedExperimentCount = completedExperimentCount;
+    }
+
+    public int getCancelledExperimentCount() {
+        return cancelledExperimentCount;
+    }
+
+    public void setCancelledExperimentCount(int cancelledExperimentCount) {
+        this.cancelledExperimentCount = cancelledExperimentCount;
+    }
+
+    public int getFailedExperimentCount() {
+        return failedExperimentCount;
+    }
+
+    public void setFailedExperimentCount(int failedExperimentCount) {
+        this.failedExperimentCount = failedExperimentCount;
+    }
+
+    public int getCreatedExperimentCount() {
+        return createdExperimentCount;
+    }
+
+    public void setCreatedExperimentCount(int createdExperimentCount) {
+        this.createdExperimentCount = createdExperimentCount;
+    }
+
+    public int getRunningExperimentCount() {
+        return runningExperimentCount;
+    }
+
+    public void setRunningExperimentCount(int runningExperimentCount) {
+        this.runningExperimentCount = runningExperimentCount;
+    }
+
+    public List<ExperimentSummaryModel> getAllExperiments() {
+        return allExperiments;
+    }
+
+    public void setAllExperiments(List<ExperimentSummaryModel> allExperiments) {
+        this.allExperiments = allExperiments;
+    }
+
+    public List<ExperimentSummaryModel> getCompletedExperiments() {
+        return completedExperiments;
+    }
+
+    public void setCompletedExperiments(List<ExperimentSummaryModel> completedExperiments) {
+        this.completedExperiments = completedExperiments;
+    }
+
+    public List<ExperimentSummaryModel> getFailedExperiments() {
+        return failedExperiments;
+    }
+
+    public void setFailedExperiments(List<ExperimentSummaryModel> failedExperiments) {
+        this.failedExperiments = failedExperiments;
+    }
+
+    public List<ExperimentSummaryModel> getCancelledExperiments() {
+        return cancelledExperiments;
+    }
+
+    public void setCancelledExperiments(List<ExperimentSummaryModel> cancelledExperiments) {
+        this.cancelledExperiments = cancelledExperiments;
+    }
+
+    public List<ExperimentSummaryModel> getCreatedExperiments() {
+        return createdExperiments;
+    }
+
+    public void setCreatedExperiments(List<ExperimentSummaryModel> createdExperiments) {
+        this.createdExperiments = createdExperiments;
+    }
+
+    public List<ExperimentSummaryModel> getRunningExperiments() {
+        return runningExperiments;
+    }
+
+    public void setRunningExperiments(List<ExperimentSummaryModel> runningExperiments) {
+        this.runningExperiments = runningExperiments;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ExperimentStatistics that = (ExperimentStatistics) o;
+        return Objects.equals(allExperimentCount, that.allExperimentCount)
+                && Objects.equals(completedExperimentCount, that.completedExperimentCount)
+                && Objects.equals(cancelledExperimentCount, that.cancelledExperimentCount)
+                && Objects.equals(failedExperimentCount, that.failedExperimentCount)
+                && Objects.equals(createdExperimentCount, that.createdExperimentCount)
+                && Objects.equals(runningExperimentCount, that.runningExperimentCount)
+                && Objects.equals(allExperiments, that.allExperiments)
+                && Objects.equals(completedExperiments, that.completedExperiments)
+                && Objects.equals(failedExperiments, that.failedExperiments)
+                && Objects.equals(cancelledExperiments, that.cancelledExperiments)
+                && Objects.equals(createdExperiments, that.createdExperiments)
+                && Objects.equals(runningExperiments, that.runningExperiments);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                allExperimentCount,
+                completedExperimentCount,
+                cancelledExperimentCount,
+                failedExperimentCount,
+                createdExperimentCount,
+                runningExperimentCount,
+                allExperiments,
+                completedExperiments,
+                failedExperiments,
+                cancelledExperiments,
+                createdExperiments,
+                runningExperiments);
+    }
+
+    @Override
+    public String toString() {
+        return "ExperimentStatistics{" + "allExperimentCount=" + allExperimentCount + ", completedExperimentCount="
+                + completedExperimentCount + ", cancelledExperimentCount=" + cancelledExperimentCount
+                + ", failedExperimentCount=" + failedExperimentCount + ", createdExperimentCount="
+                + createdExperimentCount + ", runningExperimentCount=" + runningExperimentCount + ", allExperiments="
+                + allExperiments + ", completedExperiments=" + completedExperiments + ", failedExperiments="
+                + failedExperiments + ", cancelledExperiments=" + cancelledExperiments + ", createdExperiments="
+                + createdExperiments + ", runningExperiments=" + runningExperiments + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentStatus.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentStatus.java
new file mode 100644
index 0000000000..9d59336080
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentStatus.java
@@ -0,0 +1,88 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: ExperimentStatus
+ */
+public class ExperimentStatus {
+    private ExperimentState state;
+    private long timeOfStateChange;
+    private String reason;
+    private String statusId;
+
+    public ExperimentStatus() {}
+
+    public ExperimentState getState() {
+        return state;
+    }
+
+    public void setState(ExperimentState state) {
+        this.state = state;
+    }
+
+    public long getTimeOfStateChange() {
+        return timeOfStateChange;
+    }
+
+    public void setTimeOfStateChange(long timeOfStateChange) {
+        this.timeOfStateChange = timeOfStateChange;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+    public String getStatusId() {
+        return statusId;
+    }
+
+    public void setStatusId(String statusId) {
+        this.statusId = statusId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ExperimentStatus that = (ExperimentStatus) o;
+        return Objects.equals(state, that.state)
+                && Objects.equals(timeOfStateChange, that.timeOfStateChange)
+                && Objects.equals(reason, that.reason)
+                && Objects.equals(statusId, that.statusId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(state, timeOfStateChange, reason, statusId);
+    }
+
+    @Override
+    public String toString() {
+        return "ExperimentStatus{" + "state=" + state + ", timeOfStateChange=" + timeOfStateChange + ", reason="
+                + reason + ", statusId=" + statusId + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentStatusChangeEvent.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentStatusChangeEvent.java
new file mode 100644
index 0000000000..daf3715c58
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentStatusChangeEvent.java
@@ -0,0 +1,78 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: ExperimentStatusChangeEvent
+ */
+public class ExperimentStatusChangeEvent extends MessagingEvent {
+    private ExperimentState state;
+    private String experimentId;
+    private String gatewayId;
+
+    public ExperimentStatusChangeEvent() {}
+
+    public ExperimentState getState() {
+        return state;
+    }
+
+    public void setState(ExperimentState state) {
+        this.state = state;
+    }
+
+    public String getExperimentId() {
+        return experimentId;
+    }
+
+    public void setExperimentId(String experimentId) {
+        this.experimentId = experimentId;
+    }
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public void setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ExperimentStatusChangeEvent that = (ExperimentStatusChangeEvent) o;
+        return Objects.equals(state, that.state)
+                && Objects.equals(experimentId, that.experimentId)
+                && Objects.equals(gatewayId, that.gatewayId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(state, experimentId, gatewayId);
+    }
+
+    @Override
+    public String toString() {
+        return "ExperimentStatusChangeEvent{" + "state=" + state + ", experimentId=" + experimentId + ", gatewayId="
+                + gatewayId + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentSubmitEvent.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentSubmitEvent.java
new file mode 100644
index 0000000000..782123d5ee
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentSubmitEvent.java
@@ -0,0 +1,71 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: ExperimentSubmitEvent
+ */
+public class ExperimentSubmitEvent extends MessagingEvent {
+    private String experimentId;
+    private String gatewayId;
+
+    public ExperimentSubmitEvent() {}
+
+    public ExperimentSubmitEvent(String experimentId, String gatewayId) {
+        this.experimentId = experimentId;
+        this.gatewayId = gatewayId;
+    }
+
+    public String getExperimentId() {
+        return experimentId;
+    }
+
+    public void setExperimentId(String experimentId) {
+        this.experimentId = experimentId;
+    }
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public void setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ExperimentSubmitEvent that = (ExperimentSubmitEvent) o;
+        return Objects.equals(experimentId, that.experimentId) && Objects.equals(gatewayId, that.gatewayId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(experimentId, gatewayId);
+    }
+
+    @Override
+    public String toString() {
+        return "ExperimentSubmitEvent{" + "experimentId=" + experimentId + ", gatewayId=" + gatewayId + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentSummaryModel.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentSummaryModel.java
new file mode 100644
index 0000000000..71739861a1
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentSummaryModel.java
@@ -0,0 +1,171 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: ExperimentSummaryModel
+ */
+public class ExperimentSummaryModel {
+    private String experimentId;
+    private String projectId;
+    private String gatewayId;
+    private long creationTime;
+    private String userName;
+    private String name;
+    private String description;
+    private String executionId;
+    private String resourceHostId;
+    private String experimentStatus;
+    private long statusUpdateTime;
+
+    public ExperimentSummaryModel() {}
+
+    public String getExperimentId() {
+        return experimentId;
+    }
+
+    public void setExperimentId(String experimentId) {
+        this.experimentId = experimentId;
+    }
+
+    public String getProjectId() {
+        return projectId;
+    }
+
+    public void setProjectId(String projectId) {
+        this.projectId = projectId;
+    }
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public void setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+    }
+
+    public long getCreationTime() {
+        return creationTime;
+    }
+
+    public void setCreationTime(long creationTime) {
+        this.creationTime = creationTime;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getExecutionId() {
+        return executionId;
+    }
+
+    public void setExecutionId(String executionId) {
+        this.executionId = executionId;
+    }
+
+    public String getResourceHostId() {
+        return resourceHostId;
+    }
+
+    public void setResourceHostId(String resourceHostId) {
+        this.resourceHostId = resourceHostId;
+    }
+
+    public String getExperimentStatus() {
+        return experimentStatus;
+    }
+
+    public void setExperimentStatus(String experimentStatus) {
+        this.experimentStatus = experimentStatus;
+    }
+
+    public long getStatusUpdateTime() {
+        return statusUpdateTime;
+    }
+
+    public void setStatusUpdateTime(long statusUpdateTime) {
+        this.statusUpdateTime = statusUpdateTime;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ExperimentSummaryModel that = (ExperimentSummaryModel) o;
+        return Objects.equals(experimentId, that.experimentId)
+                && Objects.equals(projectId, that.projectId)
+                && Objects.equals(gatewayId, that.gatewayId)
+                && Objects.equals(creationTime, that.creationTime)
+                && Objects.equals(userName, that.userName)
+                && Objects.equals(name, that.name)
+                && Objects.equals(description, that.description)
+                && Objects.equals(executionId, that.executionId)
+                && Objects.equals(resourceHostId, that.resourceHostId)
+                && Objects.equals(experimentStatus, that.experimentStatus)
+                && Objects.equals(statusUpdateTime, that.statusUpdateTime);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                experimentId,
+                projectId,
+                gatewayId,
+                creationTime,
+                userName,
+                name,
+                description,
+                executionId,
+                resourceHostId,
+                experimentStatus,
+                statusUpdateTime);
+    }
+
+    @Override
+    public String toString() {
+        return "ExperimentSummaryModel{" + "experimentId=" + experimentId + ", projectId=" + projectId + ", gatewayId="
+                + gatewayId + ", creationTime=" + creationTime + ", userName=" + userName + ", name=" + name
+                + ", description=" + description + ", executionId=" + executionId + ", resourceHostId=" + resourceHostId
+                + ", experimentStatus=" + experimentStatus + ", statusUpdateTime=" + statusUpdateTime + "}";
+    }
+}
diff --git a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentType.java
similarity index 58%
copy from airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentType.java
index 705d082370..9e9551928b 100644
--- a/airavata-api/src/test/java/org/apache/airavata/api/thrift/server/TestAiravataServiceServer.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/ExperimentType.java
@@ -17,18 +17,33 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.server;
+package org.apache.airavata.common.model;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/**
+ * Domain enum: ExperimentType
+ */
+public enum ExperimentType {
+    SINGLE_APPLICATION(0),
+    WORKFLOW(1);
+
+    private final int value;
 
-public class TestAiravataServiceServer {
+    ExperimentType(int value) {
+        this.value = value;
+    }
 
-    private static final Logger logger = LoggerFactory.getLogger(TestAiravataServiceServer.class);
+    public int getValue() {
+        return value;
+    }
 
-    public static void main(String[] args) {
-        throw new UnsupportedOperationException(
-                "AiravataServiceServer must be used within a Spring application context. "
-                        + "Use Spring Boot application or provide dependencies manually via constructor.");
+    public static ExperimentType findByValue(int value) {
+        switch (value) {
+            case 0:
+                return SINGLE_APPLICATION;
+            case 1:
+                return WORKFLOW;
+            default:
+                return null;
+        }
     }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/SharingRegistryConstants.java b/airavata-api/src/main/java/org/apache/airavata/common/model/FileSystems.java
similarity index 53%
copy from airavata-api/src/main/java/org/apache/airavata/api/thrift/util/SharingRegistryConstants.java
copy to airavata-api/src/main/java/org/apache/airavata/common/model/FileSystems.java
index 5ab9f782a8..e4ba22dfde 100644
--- a/airavata-api/src/main/java/org/apache/airavata/api/thrift/util/SharingRegistryConstants.java
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/FileSystems.java
@@ -17,26 +17,42 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.api.thrift.util;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.airavata.common.utils.DBEventService;
+package org.apache.airavata.common.model;
 
 /**
- * Created by Ajinkya on 3/28/17.
+ * Domain enum: FileSystems
  */
-public class SharingRegistryConstants {
-    /**
-     * List of publishers in which sharing service is interested.
-     * Add publishers as required
-     */
-    public static final List<String> PUBLISHERS = new ArrayList<String>() {
-        {
-            add(DBEventService.USER_PROFILE.toString());
-            add(DBEventService.TENANT.toString());
-            add(DBEventService.REGISTRY.toString());
-            add(DBEventService.IAM_ADMIN.toString());
+public enum FileSystems {
+    HOME(0),
+    WORK(1),
+    LOCALTMP(2),
+    SCRATCH(3),
+    ARCHIVE(4);
+
+    private final int value;
+
+    FileSystems(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static FileSystems findByValue(int value) {
+        switch (value) {
+            case 0:
+                return HOME;
+            case 1:
+                return WORK;
+            case 2:
+                return LOCALTMP;
+            case 3:
+                return SCRATCH;
+            case 4:
+                return ARCHIVE;
+            default:
+                return null;
         }
-    };
+    }
 }
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/Gateway.java b/airavata-api/src/main/java/org/apache/airavata/common/model/Gateway.java
new file mode 100644
index 0000000000..4de4357713
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/Gateway.java
@@ -0,0 +1,276 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: Gateway
+ */
+public class Gateway {
+    private String airavataInternalGatewayId;
+    private String gatewayId;
+    private GatewayApprovalStatus gatewayApprovalStatus;
+    private String gatewayName;
+    private String domain;
+    private String emailAddress;
+    private String gatewayAcronym;
+    private String gatewayURL;
+    private String gatewayPublicAbstract;
+    private String reviewProposalDescription;
+    private String gatewayAdminFirstName;
+    private String gatewayAdminLastName;
+    private String gatewayAdminEmail;
+    private String identityServerUserName;
+    private String identityServerPasswordToken;
+    private String declinedReason;
+    private String oauthClientId;
+    private String oauthClientSecret;
+    private long requestCreationTime;
+    private String requesterUsername;
+
+    public Gateway() {}
+
+    public String getAiravataInternalGatewayId() {
+        return airavataInternalGatewayId;
+    }
+
+    public void setAiravataInternalGatewayId(String airavataInternalGatewayId) {
+        this.airavataInternalGatewayId = airavataInternalGatewayId;
+    }
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public void setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+    }
+
+    public GatewayApprovalStatus getGatewayApprovalStatus() {
+        return gatewayApprovalStatus;
+    }
+
+    public void setGatewayApprovalStatus(GatewayApprovalStatus gatewayApprovalStatus) {
+        this.gatewayApprovalStatus = gatewayApprovalStatus;
+    }
+
+    public String getGatewayName() {
+        return gatewayName;
+    }
+
+    public void setGatewayName(String gatewayName) {
+        this.gatewayName = gatewayName;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public String getEmailAddress() {
+        return emailAddress;
+    }
+
+    public void setEmailAddress(String emailAddress) {
+        this.emailAddress = emailAddress;
+    }
+
+    public String getGatewayAcronym() {
+        return gatewayAcronym;
+    }
+
+    public void setGatewayAcronym(String gatewayAcronym) {
+        this.gatewayAcronym = gatewayAcronym;
+    }
+
+    public String getGatewayURL() {
+        return gatewayURL;
+    }
+
+    public void setGatewayURL(String gatewayURL) {
+        this.gatewayURL = gatewayURL;
+    }
+
+    public String getGatewayPublicAbstract() {
+        return gatewayPublicAbstract;
+    }
+
+    public void setGatewayPublicAbstract(String gatewayPublicAbstract) {
+        this.gatewayPublicAbstract = gatewayPublicAbstract;
+    }
+
+    public String getReviewProposalDescription() {
+        return reviewProposalDescription;
+    }
+
+    public void setReviewProposalDescription(String reviewProposalDescription) {
+        this.reviewProposalDescription = reviewProposalDescription;
+    }
+
+    public String getGatewayAdminFirstName() {
+        return gatewayAdminFirstName;
+    }
+
+    public void setGatewayAdminFirstName(String gatewayAdminFirstName) {
+        this.gatewayAdminFirstName = gatewayAdminFirstName;
+    }
+
+    public String getGatewayAdminLastName() {
+        return gatewayAdminLastName;
+    }
+
+    public void setGatewayAdminLastName(String gatewayAdminLastName) {
+        this.gatewayAdminLastName = gatewayAdminLastName;
+    }
+
+    public String getGatewayAdminEmail() {
+        return gatewayAdminEmail;
+    }
+
+    public void setGatewayAdminEmail(String gatewayAdminEmail) {
+        this.gatewayAdminEmail = gatewayAdminEmail;
+    }
+
+    public String getIdentityServerUserName() {
+        return identityServerUserName;
+    }
+
+    public void setIdentityServerUserName(String identityServerUserName) {
+        this.identityServerUserName = identityServerUserName;
+    }
+
+    public String getIdentityServerPasswordToken() {
+        return identityServerPasswordToken;
+    }
+
+    public void setIdentityServerPasswordToken(String identityServerPasswordToken) {
+        this.identityServerPasswordToken = identityServerPasswordToken;
+    }
+
+    public String getDeclinedReason() {
+        return declinedReason;
+    }
+
+    public void setDeclinedReason(String declinedReason) {
+        this.declinedReason = declinedReason;
+    }
+
+    public String getOauthClientId() {
+        return oauthClientId;
+    }
+
+    public void setOauthClientId(String oauthClientId) {
+        this.oauthClientId = oauthClientId;
+    }
+
+    public String getOauthClientSecret() {
+        return oauthClientSecret;
+    }
+
+    public void setOauthClientSecret(String oauthClientSecret) {
+        this.oauthClientSecret = oauthClientSecret;
+    }
+
+    public long getRequestCreationTime() {
+        return requestCreationTime;
+    }
+
+    public void setRequestCreationTime(long requestCreationTime) {
+        this.requestCreationTime = requestCreationTime;
+    }
+
+    public String getRequesterUsername() {
+        return requesterUsername;
+    }
+
+    public void setRequesterUsername(String requesterUsername) {
+        this.requesterUsername = requesterUsername;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Gateway that = (Gateway) o;
+        return Objects.equals(airavataInternalGatewayId, that.airavataInternalGatewayId)
+                && Objects.equals(gatewayId, that.gatewayId)
+                && Objects.equals(gatewayApprovalStatus, that.gatewayApprovalStatus)
+                && Objects.equals(gatewayName, that.gatewayName)
+                && Objects.equals(domain, that.domain)
+                && Objects.equals(emailAddress, that.emailAddress)
+                && Objects.equals(gatewayAcronym, that.gatewayAcronym)
+                && Objects.equals(gatewayURL, that.gatewayURL)
+                && Objects.equals(gatewayPublicAbstract, that.gatewayPublicAbstract)
+                && Objects.equals(reviewProposalDescription, that.reviewProposalDescription)
+                && Objects.equals(gatewayAdminFirstName, that.gatewayAdminFirstName)
+                && Objects.equals(gatewayAdminLastName, that.gatewayAdminLastName)
+                && Objects.equals(gatewayAdminEmail, that.gatewayAdminEmail)
+                && Objects.equals(identityServerUserName, that.identityServerUserName)
+                && Objects.equals(identityServerPasswordToken, that.identityServerPasswordToken)
+                && Objects.equals(declinedReason, that.declinedReason)
+                && Objects.equals(oauthClientId, that.oauthClientId)
+                && Objects.equals(oauthClientSecret, that.oauthClientSecret)
+                && Objects.equals(requestCreationTime, that.requestCreationTime)
+                && Objects.equals(requesterUsername, that.requesterUsername);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                airavataInternalGatewayId,
+                gatewayId,
+                gatewayApprovalStatus,
+                gatewayName,
+                domain,
+                emailAddress,
+                gatewayAcronym,
+                gatewayURL,
+                gatewayPublicAbstract,
+                reviewProposalDescription,
+                gatewayAdminFirstName,
+                gatewayAdminLastName,
+                gatewayAdminEmail,
+                identityServerUserName,
+                identityServerPasswordToken,
+                declinedReason,
+                oauthClientId,
+                oauthClientSecret,
+                requestCreationTime,
+                requesterUsername);
+    }
+
+    @Override
+    public String toString() {
+        return "Gateway{" + "airavataInternalGatewayId=" + airavataInternalGatewayId + ", gatewayId=" + gatewayId
+                + ", gatewayApprovalStatus=" + gatewayApprovalStatus + ", gatewayName=" + gatewayName + ", domain="
+                + domain + ", emailAddress=" + emailAddress + ", gatewayAcronym=" + gatewayAcronym + ", gatewayURL="
+                + gatewayURL + ", gatewayPublicAbstract=" + gatewayPublicAbstract + ", reviewProposalDescription="
+                + reviewProposalDescription + ", gatewayAdminFirstName=" + gatewayAdminFirstName
+                + ", gatewayAdminLastName=" + gatewayAdminLastName + ", gatewayAdminEmail=" + gatewayAdminEmail
+                + ", identityServerUserName=" + identityServerUserName + ", identityServerPasswordToken="
+                + identityServerPasswordToken + ", declinedReason=" + declinedReason + ", oauthClientId="
+                + oauthClientId + ", oauthClientSecret=" + oauthClientSecret + ", requestCreationTime="
+                + requestCreationTime + ", requesterUsername=" + requesterUsername + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayApprovalStatus.java b/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayApprovalStatus.java
new file mode 100644
index 0000000000..c68834adec
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayApprovalStatus.java
@@ -0,0 +1,67 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+/**
+ * Domain enum: GatewayApprovalStatus
+ */
+public enum GatewayApprovalStatus {
+    REQUESTED(0),
+    APPROVED(1),
+    ACTIVE(2),
+    DEACTIVATED(3),
+    CANCELLED(4),
+    DENIED(5),
+    CREATED(6),
+    DEPLOYED(7);
+
+    private final int value;
+
+    GatewayApprovalStatus(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static GatewayApprovalStatus findByValue(int value) {
+        switch (value) {
+            case 0:
+                return REQUESTED;
+            case 1:
+                return APPROVED;
+            case 2:
+                return ACTIVE;
+            case 3:
+                return DEACTIVATED;
+            case 4:
+                return CANCELLED;
+            case 5:
+                return DENIED;
+            case 6:
+                return CREATED;
+            case 7:
+                return DEPLOYED;
+            default:
+                return null;
+        }
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayGroups.java b/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayGroups.java
new file mode 100644
index 0000000000..6aba1182ae
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayGroups.java
@@ -0,0 +1,89 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: GatewayGroups
+ */
+public class GatewayGroups {
+    private String gatewayId;
+    private String adminsGroupId;
+    private String readOnlyAdminsGroupId;
+    private String defaultGatewayUsersGroupId;
+
+    public GatewayGroups() {}
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public void setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+    }
+
+    public String getAdminsGroupId() {
+        return adminsGroupId;
+    }
+
+    public void setAdminsGroupId(String adminsGroupId) {
+        this.adminsGroupId = adminsGroupId;
+    }
+
+    public String getReadOnlyAdminsGroupId() {
+        return readOnlyAdminsGroupId;
+    }
+
+    public void setReadOnlyAdminsGroupId(String readOnlyAdminsGroupId) {
+        this.readOnlyAdminsGroupId = readOnlyAdminsGroupId;
+    }
+
+    public String getDefaultGatewayUsersGroupId() {
+        return defaultGatewayUsersGroupId;
+    }
+
+    public void setDefaultGatewayUsersGroupId(String defaultGatewayUsersGroupId) {
+        this.defaultGatewayUsersGroupId = defaultGatewayUsersGroupId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        GatewayGroups that = (GatewayGroups) o;
+        return Objects.equals(gatewayId, that.gatewayId)
+                && Objects.equals(adminsGroupId, that.adminsGroupId)
+                && Objects.equals(readOnlyAdminsGroupId, that.readOnlyAdminsGroupId)
+                && Objects.equals(defaultGatewayUsersGroupId, that.defaultGatewayUsersGroupId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(gatewayId, adminsGroupId, readOnlyAdminsGroupId, defaultGatewayUsersGroupId);
+    }
+
+    @Override
+    public String toString() {
+        return "GatewayGroups{" + "gatewayId=" + gatewayId + ", adminsGroupId=" + adminsGroupId
+                + ", readOnlyAdminsGroupId=" + readOnlyAdminsGroupId + ", defaultGatewayUsersGroupId="
+                + defaultGatewayUsersGroupId + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayResourceProfile.java b/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayResourceProfile.java
new file mode 100644
index 0000000000..c4450cf590
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayResourceProfile.java
@@ -0,0 +1,117 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: GatewayResourceProfile
+ */
+public class GatewayResourceProfile {
+    private String gatewayID;
+    private String credentialStoreToken;
+    private List<ComputeResourcePreference> computeResourcePreferences;
+    private List<StoragePreference> storagePreferences;
+    private String identityServerTenant;
+    private String identityServerPwdCredToken;
+
+    public GatewayResourceProfile() {}
+
+    public String getGatewayID() {
+        return gatewayID;
+    }
+
+    public void setGatewayID(String gatewayID) {
+        this.gatewayID = gatewayID;
+    }
+
+    public String getCredentialStoreToken() {
+        return credentialStoreToken;
+    }
+
+    public void setCredentialStoreToken(String credentialStoreToken) {
+        this.credentialStoreToken = credentialStoreToken;
+    }
+
+    public List<ComputeResourcePreference> getComputeResourcePreferences() {
+        return computeResourcePreferences;
+    }
+
+    public void setComputeResourcePreferences(List<ComputeResourcePreference> computeResourcePreferences) {
+        this.computeResourcePreferences = computeResourcePreferences;
+    }
+
+    public List<StoragePreference> getStoragePreferences() {
+        return storagePreferences;
+    }
+
+    public void setStoragePreferences(List<StoragePreference> storagePreferences) {
+        this.storagePreferences = storagePreferences;
+    }
+
+    public String getIdentityServerTenant() {
+        return identityServerTenant;
+    }
+
+    public void setIdentityServerTenant(String identityServerTenant) {
+        this.identityServerTenant = identityServerTenant;
+    }
+
+    public String getIdentityServerPwdCredToken() {
+        return identityServerPwdCredToken;
+    }
+
+    public void setIdentityServerPwdCredToken(String identityServerPwdCredToken) {
+        this.identityServerPwdCredToken = identityServerPwdCredToken;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        GatewayResourceProfile that = (GatewayResourceProfile) o;
+        return Objects.equals(gatewayID, that.gatewayID)
+                && Objects.equals(credentialStoreToken, that.credentialStoreToken)
+                && Objects.equals(computeResourcePreferences, that.computeResourcePreferences)
+                && Objects.equals(storagePreferences, that.storagePreferences)
+                && Objects.equals(identityServerTenant, that.identityServerTenant)
+                && Objects.equals(identityServerPwdCredToken, that.identityServerPwdCredToken);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                gatewayID,
+                credentialStoreToken,
+                computeResourcePreferences,
+                storagePreferences,
+                identityServerTenant,
+                identityServerPwdCredToken);
+    }
+
+    @Override
+    public String toString() {
+        return "GatewayResourceProfile{" + "gatewayID=" + gatewayID + ", credentialStoreToken=" + credentialStoreToken
+                + ", computeResourcePreferences=" + computeResourcePreferences + ", storagePreferences="
+                + storagePreferences + ", identityServerTenant=" + identityServerTenant
+                + ", identityServerPwdCredToken=" + identityServerPwdCredToken + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayUsageReportingCommand.java b/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayUsageReportingCommand.java
new file mode 100644
index 0000000000..d63bb3a157
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/GatewayUsageReportingCommand.java
@@ -0,0 +1,78 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: GatewayUsageReportingCommand
+ */
+public class GatewayUsageReportingCommand {
+    private String gatewayId;
+    private String computeResourceId;
+    private String command;
+
+    public GatewayUsageReportingCommand() {}
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public void setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+    }
+
+    public String getComputeResourceId() {
+        return computeResourceId;
+    }
+
+    public void setComputeResourceId(String computeResourceId) {
+        this.computeResourceId = computeResourceId;
+    }
+
+    public String getCommand() {
+        return command;
+    }
+
+    public void setCommand(String command) {
+        this.command = command;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        GatewayUsageReportingCommand that = (GatewayUsageReportingCommand) o;
+        return Objects.equals(gatewayId, that.gatewayId)
+                && Objects.equals(computeResourceId, that.computeResourceId)
+                && Objects.equals(command, that.command);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(gatewayId, computeResourceId, command);
+    }
+
+    @Override
+    public String toString() {
+        return "GatewayUsageReportingCommand{" + "gatewayId=" + gatewayId + ", computeResourceId=" + computeResourceId
+                + ", command=" + command + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/GlobusJobSubmission.java b/airavata-api/src/main/java/org/apache/airavata/common/model/GlobusJobSubmission.java
new file mode 100644
index 0000000000..1e33931f14
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/GlobusJobSubmission.java
@@ -0,0 +1,79 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: GlobusJobSubmission
+ */
+public class GlobusJobSubmission {
+    private String jobSubmissionInterfaceId;
+    private SecurityProtocol securityProtocol;
+    private List<String> globusGateKeeperEndPoint;
+
+    public GlobusJobSubmission() {}
+
+    public String getJobSubmissionInterfaceId() {
+        return jobSubmissionInterfaceId;
+    }
+
+    public void setJobSubmissionInterfaceId(String jobSubmissionInterfaceId) {
+        this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
+    }
+
+    public SecurityProtocol getSecurityProtocol() {
+        return securityProtocol;
+    }
+
+    public void setSecurityProtocol(SecurityProtocol securityProtocol) {
+        this.securityProtocol = securityProtocol;
+    }
+
+    public List<String> getGlobusGateKeeperEndPoint() {
+        return globusGateKeeperEndPoint;
+    }
+
+    public void setGlobusGateKeeperEndPoint(List<String> globusGateKeeperEndPoint) {
+        this.globusGateKeeperEndPoint = globusGateKeeperEndPoint;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        GlobusJobSubmission that = (GlobusJobSubmission) o;
+        return Objects.equals(jobSubmissionInterfaceId, that.jobSubmissionInterfaceId)
+                && Objects.equals(securityProtocol, that.securityProtocol)
+                && Objects.equals(globusGateKeeperEndPoint, that.globusGateKeeperEndPoint);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(jobSubmissionInterfaceId, securityProtocol, globusGateKeeperEndPoint);
+    }
+
+    @Override
+    public String toString() {
+        return "GlobusJobSubmission{" + "jobSubmissionInterfaceId=" + jobSubmissionInterfaceId + ", securityProtocol="
+                + securityProtocol + ", globusGateKeeperEndPoint=" + globusGateKeeperEndPoint + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/GridFTPDataMovement.java b/airavata-api/src/main/java/org/apache/airavata/common/model/GridFTPDataMovement.java
new file mode 100644
index 0000000000..7fa3b92f07
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/GridFTPDataMovement.java
@@ -0,0 +1,79 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Domain model: GridFTPDataMovement
+ */
+public class GridFTPDataMovement {
+    private String dataMovementInterfaceId;
+    private SecurityProtocol securityProtocol;
+    private List<String> gridFTPEndPoints;
+
+    public GridFTPDataMovement() {}
+
+    public String getDataMovementInterfaceId() {
+        return dataMovementInterfaceId;
+    }
+
+    public void setDataMovementInterfaceId(String dataMovementInterfaceId) {
+        this.dataMovementInterfaceId = dataMovementInterfaceId;
+    }
+
+    public SecurityProtocol getSecurityProtocol() {
+        return securityProtocol;
+    }
+
+    public void setSecurityProtocol(SecurityProtocol securityProtocol) {
+        this.securityProtocol = securityProtocol;
+    }
+
+    public List<String> getGridFTPEndPoints() {
+        return gridFTPEndPoints;
+    }
+
+    public void setGridFTPEndPoints(List<String> gridFTPEndPoints) {
+        this.gridFTPEndPoints = gridFTPEndPoints;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        GridFTPDataMovement that = (GridFTPDataMovement) o;
+        return Objects.equals(dataMovementInterfaceId, that.dataMovementInterfaceId)
+                && Objects.equals(securityProtocol, that.securityProtocol)
+                && Objects.equals(gridFTPEndPoints, that.gridFTPEndPoints);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(dataMovementInterfaceId, securityProtocol, gridFTPEndPoints);
+    }
+
+    @Override
+    public String toString() {
+        return "GridFTPDataMovement{" + "dataMovementInterfaceId=" + dataMovementInterfaceId + ", securityProtocol="
+                + securityProtocol + ", gridFTPEndPoints=" + gridFTPEndPoints + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/Group.java b/airavata-api/src/main/java/org/apache/airavata/common/model/Group.java
new file mode 100644
index 0000000000..df2f8a8c92
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/Group.java
@@ -0,0 +1,66 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: Group
+ */
+public class Group {
+    private String groupName;
+    private String description;
+
+    public Group() {}
+
+    public String getGroupName() {
+        return groupName;
+    }
+
+    public void setGroupName(String groupName) {
+        this.groupName = groupName;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Group that = (Group) o;
+        return Objects.equals(groupName, that.groupName) && Objects.equals(description, that.description);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(groupName, description);
+    }
+
+    @Override
+    public String toString() {
+        return "Group{" + "groupName=" + groupName + ", description=" + description + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/GroupAccountSSHProvisionerConfig.java b/airavata-api/src/main/java/org/apache/airavata/common/model/GroupAccountSSHProvisionerConfig.java
new file mode 100644
index 0000000000..3a16247c5f
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/GroupAccountSSHProvisionerConfig.java
@@ -0,0 +1,88 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: GroupAccountSSHProvisionerConfig
+ */
+public class GroupAccountSSHProvisionerConfig {
+    private String resourceId;
+    private String groupResourceProfileId;
+    private String configName;
+    private String configValue;
+
+    public GroupAccountSSHProvisionerConfig() {}
+
+    public String getResourceId() {
+        return resourceId;
+    }
+
+    public void setResourceId(String resourceId) {
+        this.resourceId = resourceId;
+    }
+
+    public String getGroupResourceProfileId() {
+        return groupResourceProfileId;
+    }
+
+    public void setGroupResourceProfileId(String groupResourceProfileId) {
+        this.groupResourceProfileId = groupResourceProfileId;
+    }
+
+    public String getConfigName() {
+        return configName;
+    }
+
+    public void setConfigName(String configName) {
+        this.configName = configName;
+    }
+
+    public String getConfigValue() {
+        return configValue;
+    }
+
+    public void setConfigValue(String configValue) {
+        this.configValue = configValue;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        GroupAccountSSHProvisionerConfig that = (GroupAccountSSHProvisionerConfig) o;
+        return Objects.equals(resourceId, that.resourceId)
+                && Objects.equals(groupResourceProfileId, that.groupResourceProfileId)
+                && Objects.equals(configName, that.configName)
+                && Objects.equals(configValue, that.configValue);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(resourceId, groupResourceProfileId, configName, configValue);
+    }
+
+    @Override
+    public String toString() {
+        return "GroupAccountSSHProvisionerConfig{" + "resourceId=" + resourceId + ", groupResourceProfileId="
+                + groupResourceProfileId + ", configName=" + configName + ", configValue=" + configValue + "}";
+    }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/model/GroupComputeResourcePreference.java b/airavata-api/src/main/java/org/apache/airavata/common/model/GroupComputeResourcePreference.java
new file mode 100644
index 0000000000..fe23d3a31c
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/model/GroupComputeResourcePreference.java
@@ -0,0 +1,163 @@
+/**
+*
+* 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
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.airavata.common.model;
+
+import java.util.Objects;
+
+/**
+ * Domain model: GroupComputeResourcePreference
+ */
+public class GroupComputeResourcePreference {
+    private String computeResourceId;
+    private String groupResourceProfileId;
+    private boolean overridebyAiravata;
+    private String loginUserName;
+    private String scratchLocation;
+    private JobSubmissionProtocol preferredJobSubmissionProtocol;
+    private DataMovementProtocol preferredDataMovementProtocol;
+    private String resourceSpecificCredentialStoreToken;
+    private ComputeResourceType resourceType;
+    private EnvironmentSpecificPreferences specificPreferences;
+
+    public GroupComputeResourcePreference() {}
+
+    public String getComputeResourceId() {
+        return computeResourceId;
+    }
+
+    public void setComputeResourceId(String computeResourceId) {
+        this.computeResourceId = computeResourceId;
+    }
+
+    public String getGroupResourceProfileId() {
+        return groupResourceProfileId;
+    }
+
+    public void setGroupResourceProfileId(String groupResourceProfileId) {
+        this.groupResourceProfileId = groupResourceProfileId;
+    }
+
+    public boolean getOverridebyAiravata() {
+        return overridebyAiravata;
+    }
+
+    public void setOverridebyAiravata(boolean overridebyAiravata) {
+        this.overridebyAiravata = overridebyAiravata;
+    }
+
+    public String getLoginUserName() {
+        return loginUserName;
+    }
+
+    public void setLoginUserName(String loginUserName) {
+        this.loginUserName = loginUserName;
+    }
+
+    public String getScratchLocation() {
+        return scratchLocation;
+    }
+
+    public void setScratchLocation(String scratchLocation) {
+        this.scratchLocation = scratchLocation;
+    }
+
+    public JobSubmissionProtocol getPreferredJobSubmissionProtocol() {
+        return preferredJobSubmissionProtocol;
+    }
+
+    public void setPreferredJobSubmissionProtocol(JobSubmissionProtocol preferredJobSubmissionProtocol) {
+        this.preferredJobSubmissionProtocol = preferredJobSubmissionProtocol;
+    }
+
+    public DataMovementProtocol getPreferredDataMovementProtocol() {
+        return preferredDataMovementProtocol;
+    }
+
+    public void setPreferredDataMovementProtocol(DataMovementProtocol preferredDataMovementProtocol) {
+        this.preferredDataMovementProtocol = preferredDataMovementProtocol;
+    }
+
+    public String getResourceSpecificCredentialStoreToken() {
+        return resourceSpecificCredentialStoreToken;
+    }
... 31665 lines suppressed ...