eagle-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From h..@apache.org
Subject [11/11] incubator-eagle git commit: [EAGLE-382][EAGLE-385] Monitoring Application Framework Core
Date Thu, 21 Jul 2016 12:28:55 GMT
[EAGLE-382][EAGLE-385] Monitoring Application Framework Core

https://issues.apache.org/jira/browse/EAGLE-382

Author: Hao Chen <hao@apache.org>

Closes #270 from haoch/EAGLE-382.


Project: http://git-wip-us.apache.org/repos/asf/incubator-eagle/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-eagle/commit/e21b073f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-eagle/tree/e21b073f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-eagle/diff/e21b073f

Branch: refs/heads/develop
Commit: e21b073f6a21e2b9b6aa580d11dbadfa474c9c4c
Parents: f0af3e5
Author: Hao Chen <hao@apache.org>
Authored: Thu Jul 21 20:28:32 2016 +0800
Committer: Hao Chen <hao@apache.org>
Committed: Thu Jul 21 20:28:32 2016 +0800

----------------------------------------------------------------------
 .../alert/engine/coordinator/StreamColumn.java  |  64 ++++
 .../engine/coordinator/StreamDefinition.java    |   5 +-
 .../engine/mock/MockSampleMetadataFactory.java  |   5 -
 .../metadata/resource/MetadataResource.java     |  11 +-
 .../alert-metadata/pom.xml                      |   5 +
 .../metadata/impl/InMemMetadataDaoImpl.java     |   4 +-
 .../metadata/impl/JdbcDatabaseHandler.java      |   8 +-
 .../metadata/impl/JdbcMetadataDaoImpl.java      |   2 +
 .../metadata/impl/MongoMetadataDaoImpl.java     |   2 +
 .../apache/eagle/service/app/ServiceApp.java    |   7 +-
 .../eagle-alert-parent/eagle-alert/pom.xml      |  36 ---
 eagle-core/eagle-app/eagle-app-base/pom.xml     | 106 +++++++
 .../apache/eagle/app/AbstractApplication.java   | 143 +++++++++
 .../java/org/apache/eagle/app/Application.java  |  40 +++
 .../apache/eagle/app/ApplicationContext.java    | 108 +++++++
 .../eagle/app/ApplicationGuiceModule.java       |  36 +++
 .../app/config/ApplicationProviderConfig.java   |  55 ++++
 .../config/ApplicationProviderDescConfig.java   | 147 +++++++++
 .../app/config/ApplicationProvidersConfig.java  |  39 +++
 .../eagle/app/resource/ApplicationResource.java | 155 ++++++++++
 .../apache/eagle/app/service/AppOperations.java | 161 ++++++++++
 .../service/ApplicationManagementService.java   |  49 +++
 .../ApplicationManagementServiceImpl.java       |  96 ++++++
 .../app/service/ApplicationProviderLoader.java  |  74 +++++
 .../app/service/ApplicationProviderService.java |  31 ++
 .../service/ApplicationProviderServiceImpl.java |  87 ++++++
 .../loader/ApplicationProviderConfigLoader.java | 128 ++++++++
 .../loader/ApplicationProviderSPILoader.java    |  89 ++++++
 .../apache/eagle/app/sink/KafkaStreamSink.java  |  65 ++++
 .../eagle/app/sink/LoggingStreamSink.java       |  43 +++
 .../org/apache/eagle/app/sink/StreamSink.java   |  82 +++++
 .../app/spi/AbstractApplicationProvider.java    | 144 +++++++++
 .../eagle/app/spi/ApplicationProvider.java      |  37 +++
 .../org/apache/eagle/app/test/AppSimulator.java |  51 ++++
 .../apache/eagle/app/test/AppSimulatorImpl.java |  89 ++++++
 .../eagle/app/test/AppTestGuiceModule.java      |  33 ++
 .../eagle/app/test/AppUnitTestRunner.java       |  84 +++++
 .../java/org/apache/eagle/app/test/Modules.java |  39 +++
 .../org/apache/eagle/app/test/package-info.java |  46 +++
 .../eagle/app/tools/DynamicJarPathFinder.java   | 121 ++++++++
 .../src/main/resources/applications.xml         |  42 +++
 .../src/main/resources/log4j.properties         |  21 ++
 .../app/ApplicationProviderDescConfigTest.java  |  53 ++++
 .../app/ApplicationProviderServiceTest.java     |  47 +++
 .../eagle/app/ConfigurationHelperTest.java      |  33 ++
 .../org/apache/eagle/app/StreamDefinitions.java |  37 +++
 .../apache/eagle/app/TestApplicationImpl.java   |  82 +++++
 .../eagle/app/TestApplicationTestSuite.java     |  82 +++++
 .../test/resources/ExampleApplicationConf.xml   |  31 ++
 ...org.apache.eagle.app.spi.ApplicationProvider |  16 +
 .../src/test/resources/TestApplicationConf.xml  |  31 ++
 .../test/resources/TestApplicationMetadata.xml  | 103 +++++++
 .../test/resources/TestStreamDefinitionConf.xml |  37 +++
 .../src/test/resources/application.conf         |  54 ++++
 .../src/test/resources/config_template.xml      |  35 +++
 .../src/test/resources/log4j.properties         |  21 ++
 .../src/test/resources/providers.xml            |  23 ++
 .../eagle-app/eagle-application-service/pom.xml |  54 ++++
 .../application/AppManagerConstants.java        |  43 +++
 .../ApplicationManagementResource.java          | 109 +++++++
 .../application/dao/ApplicationManagerDAO.java  |  33 ++
 .../dao/ApplicationManagerDaoImpl.java          |  91 ++++++
 .../entity/ApplicationEntityRepo.java           |  30 ++
 .../entity/TopologyDescriptionEntity.java       | 104 +++++++
 .../entity/TopologyExecutionEntity.java         | 132 ++++++++
 .../entity/TopologyExecutionStatus.java         |  38 +++
 .../entity/TopologyOperationEntity.java         | 105 +++++++
 .../eagle-stream-application-manager/pom.xml    | 142 +++++++++
 .../stream/application/TopologyException.java   |  26 ++
 .../stream/application/TopologyExecutable.java  |  27 ++
 .../stream/application/TopologyFactory.java     |  55 ++++
 .../AbstractDynamicApplication.scala            |  32 ++
 .../stream/application/ApplicationManager.scala | 126 ++++++++
 .../application/ApplicationManagerUtils.scala   |  38 +++
 .../ApplicationSchedulerAsyncDAO.scala          | 179 +++++++++++
 .../stream/application/ExecutionPlatform.scala  |  30 ++
 .../application/ExecutionPlatformFactory.scala  |  49 +++
 .../eagle/stream/application/TaskExecutor.scala |  41 +++
 .../application/impl/StormDynamicTopology.scala |  44 +++
 .../impl/StormExecutionPlatform.scala           | 197 ++++++++++++
 .../scheduler/AppCommandExecutor.scala          | 170 +++++++++++
 .../scheduler/AppCommandLoader.scala            |  78 +++++
 .../scheduler/ApplicationScheduler.scala        |  81 +++++
 .../scheduler/StreamAppCoordinator.scala        |  54 ++++
 .../src/test/resources/application.conf         |  42 +++
 .../src/test/resources/log4j.properties         |  35 +++
 .../application/scheduler/MockTopology.scala    |  30 ++
 .../scheduler/StormApplicationManagerSpec.scala |  40 +++
 .../application/scheduler/TestScheduler.scala   |  61 ++++
 eagle-core/eagle-app/pom.xml                    |  38 +++
 .../eagle-application-service/pom.xml           |  54 ----
 .../application/AppManagerConstants.java        |  43 ---
 .../ApplicationManagementResource.java          | 109 -------
 .../application/dao/ApplicationManagerDAO.java  |  33 --
 .../dao/ApplicationManagerDaoImpl.java          |  91 ------
 .../entity/ApplicationEntityRepo.java           |  30 --
 .../entity/TopologyDescriptionEntity.java       | 104 -------
 .../entity/TopologyExecutionEntity.java         | 132 --------
 .../entity/TopologyExecutionStatus.java         |  38 ---
 .../entity/TopologyOperationEntity.java         | 105 -------
 .../eagle-stream-application-manager/pom.xml    | 142 ---------
 .../stream/application/TopologyException.java   |  26 --
 .../stream/application/TopologyExecutable.java  |  27 --
 .../stream/application/TopologyFactory.java     |  55 ----
 .../AbstractDynamicApplication.scala            |  32 --
 .../stream/application/ApplicationManager.scala | 126 --------
 .../application/ApplicationManagerUtils.scala   |  38 ---
 .../ApplicationSchedulerAsyncDAO.scala          | 179 -----------
 .../stream/application/ExecutionPlatform.scala  |  30 --
 .../application/ExecutionPlatformFactory.scala  |  49 ---
 .../eagle/stream/application/TaskExecutor.scala |  41 ---
 .../application/impl/StormDynamicTopology.scala |  44 ---
 .../impl/StormExecutionPlatform.scala           | 197 ------------
 .../scheduler/AppCommandExecutor.scala          | 170 -----------
 .../scheduler/AppCommandLoader.scala            |  78 -----
 .../scheduler/ApplicationScheduler.scala        |  81 -----
 .../scheduler/StreamAppCoordinator.scala        |  54 ----
 .../src/test/resources/application.conf         |  42 ---
 .../src/test/resources/log4j.properties         |  35 ---
 .../application/scheduler/MockTopology.scala    |  30 --
 .../scheduler/StormApplicationManagerSpec.scala |  40 ---
 .../application/scheduler/TestScheduler.scala   |  61 ----
 eagle-core/eagle-application-management/pom.xml |  38 ---
 eagle-core/eagle-common/pom.xml                 |  82 +++++
 .../src/main/java/META-INF/MANIFEST.MF          |  19 ++
 .../java/org/apache/eagle/common/Base64.java    |  44 +++
 .../java/org/apache/eagle/common/ByteUtil.java  | 178 +++++++++++
 .../apache/eagle/common/CircularArrayList.java  | 149 +++++++++
 .../common/CircularArrayListSortedSet.java      | 106 +++++++
 .../org/apache/eagle/common/DateTimeUtil.java   | 150 +++++++++
 .../apache/eagle/common/EagleBase64Wrapper.java |  32 ++
 .../eagle/common/EagleExceptionWrapper.java     |  42 +++
 .../org/apache/eagle/common/Environment.java    |  23 ++
 .../main/java/org/apache/eagle/common/OS.java   |  41 +++
 .../apache/eagle/common/SerializableUtils.java  | 126 ++++++++
 .../apache/eagle/common/config/EagleConfig.java |  60 ++++
 .../common/config/EagleConfigConstants.java     |  65 ++++
 .../eagle/common/config/EagleConfigFactory.java | 198 ++++++++++++
 .../eagle/common/config/EagleConfigHelper.java  |  51 ++++
 .../eagle/common/email/EagleMailClient.java     | 253 ++++++++++++++++
 .../eagle/common/metric/AlertContext.java       |  94 ++++++
 .../eagle/common/module/CommonGuiceModule.java  |  28 ++
 .../common/module/ConfigServiceProvider.java    |  30 ++
 .../common/service/HadoopAccountService.java    |  23 ++
 .../apache/eagle/common/service/HadoopUser.java |  44 +++
 .../eagle/common/service/LdapService.java       | 259 ++++++++++++++++
 .../common/service/POSTResultEntityBase.java    |  42 +++
 .../service/TrustAllSSLSocketFactory.java       |  94 ++++++
 .../eagle-common/src/main/resources/footer.vm   |  25 ++
 .../eagle-common/src/main/resources/header.vm   | 303 +++++++++++++++++++
 .../src/main/resources/templates/tec_alert.vm   | 113 +++++++
 .../org/apache/eagle/common/TestByteUtil.java   | 111 +++++++
 .../eagle/common/TestCircularArrayList.java     |  74 +++++
 .../common/TestCircularArrayListSortedSet.java  |  58 ++++
 .../apache/eagle/common/TestDateTimeUtil.java   |  87 ++++++
 .../eagle/common/TestEagleBase64Wrapper.java    |  38 +++
 .../eagle/common/config/TestEagleConfig.java    |  43 +++
 .../eagle/common/metric/TestAlertContext.java   |  39 +++
 .../eagle-common/src/test/resources/footer.vm   |  25 ++
 .../eagle-common/src/test/resources/header.vm   | 299 ++++++++++++++++++
 .../src/test/resources/log4j.properties         |  34 +++
 .../src/test/resources/templates/tec_alert.vm   | 119 ++++++++
 .../resources/templates/test_anomaly_alert.vm   | 137 +++++++++
 .../src/test/resources/test-service-config.conf |  30 ++
 .../eagle-metadata/eagle-metadata-base/pom.xml  |  53 ++++
 .../eagle/metadata/model/ApplicationDesc.java   | 141 +++++++++
 .../eagle/metadata/model/ApplicationDocs.java   |  38 +++
 .../eagle/metadata/model/ApplicationEntity.java | 153 ++++++++++
 .../metadata/model/ApplicationRawEntity.java    |  72 +++++
 .../eagle/metadata/model/Configuration.java     |  74 +++++
 .../apache/eagle/metadata/model/Property.java   |  56 ++++
 .../apache/eagle/metadata/model/SiteEntity.java |  68 +++++
 .../apache/eagle/metadata/model/StreamDesc.java |  60 ++++
 .../persistence/MemoryMetadataStore.java        |  33 ++
 .../metadata/persistence/MetadataStore.java     |  50 +++
 .../metadata/persistence/PersistenceEntity.java |  64 ++++
 .../persistence/PersistenceService.java         |  25 ++
 .../metadata/persistence/package-info.java      |  17 ++
 .../eagle/metadata/resource/RestResponse.java   | 259 ++++++++++++++++
 .../eagle/metadata/resource/SiteResource.java   |  59 ++++
 .../metadata/resource/UncheckedFunction.java    |  29 ++
 .../metadata/resource/UnhandledConsumer.java    |  22 ++
 .../metadata/resource/UnhandledSupplier.java    |  29 ++
 .../service/ApplicationDescService.java         |  26 ++
 .../service/ApplicationEntityService.java       |  30 ++
 .../metadata/service/SiteEntityService.java     |  25 ++
 .../ApplicationEntityServiceMemoryImpl.java     | 101 +++++++
 .../SiteEntityEntityServiceMemoryImpl.java      |  64 ++++
 .../metadata/utils/ConfigTemplateHelper.java    |  68 +++++
 .../eagle/metadata/utils/UUIDGenerator.java     |  25 ++
 .../eagle-metadata/eagle-metadata-jdbc/pom.xml  |  37 +++
 .../store/mysql/MySQLMetadataStore.java         |  29 ++
 .../eagle-metadata/eagle-metadata-mongo/pom.xml |  37 +++
 .../store/mongo/MongoMetadataStore.java         |  29 ++
 eagle-core/eagle-metadata/pom.xml               |  36 +++
 eagle-core/eagle-query/eagle-common/pom.xml     |  83 -----
 .../src/main/java/META-INF/MANIFEST.MF          |  19 --
 .../java/org/apache/eagle/common/Base64.java    |  44 ---
 .../java/org/apache/eagle/common/ByteUtil.java  | 178 -----------
 .../apache/eagle/common/CircularArrayList.java  | 149 ---------
 .../common/CircularArrayListSortedSet.java      | 106 -------
 .../org/apache/eagle/common/DateTimeUtil.java   | 150 ---------
 .../apache/eagle/common/EagleBase64Wrapper.java |  32 --
 .../eagle/common/EagleExceptionWrapper.java     |  42 ---
 .../org/apache/eagle/common/Environment.java    |  23 --
 .../main/java/org/apache/eagle/common/OS.java   |  41 ---
 .../apache/eagle/common/SerializableUtils.java  | 126 --------
 .../apache/eagle/common/config/EagleConfig.java |  60 ----
 .../common/config/EagleConfigConstants.java     |  65 ----
 .../eagle/common/config/EagleConfigFactory.java | 198 ------------
 .../eagle/common/config/EagleConfigHelper.java  |  51 ----
 .../eagle/common/email/EagleMailClient.java     | 253 ----------------
 .../eagle/common/metric/AlertContext.java       |  95 ------
 .../common/service/HadoopAccountService.java    |  23 --
 .../apache/eagle/common/service/HadoopUser.java |  44 ---
 .../eagle/common/service/LdapService.java       | 259 ----------------
 .../common/service/POSTResultEntityBase.java    |  42 ---
 .../service/TrustAllSSLSocketFactory.java       |  94 ------
 .../eagle-common/src/main/resources/footer.vm   |  25 --
 .../eagle-common/src/main/resources/header.vm   | 303 -------------------
 .../src/main/resources/templates/tec_alert.vm   | 113 -------
 .../org/apache/eagle/common/TestByteUtil.java   | 111 -------
 .../eagle/common/TestCircularArrayList.java     |  74 -----
 .../common/TestCircularArrayListSortedSet.java  |  58 ----
 .../apache/eagle/common/TestDateTimeUtil.java   |  87 ------
 .../eagle/common/TestEagleBase64Wrapper.java    |  38 ---
 .../eagle/common/config/TestEagleConfig.java    |  43 ---
 .../eagle/common/metric/TestAlertContext.java   |  39 ---
 .../eagle-common/src/test/resources/footer.vm   |  25 --
 .../eagle-common/src/test/resources/header.vm   | 299 ------------------
 .../src/test/resources/log4j.properties         |  34 ---
 .../src/test/resources/templates/tec_alert.vm   | 119 --------
 .../resources/templates/test_anomaly_alert.vm   | 137 ---------
 .../src/test/resources/test-service-config.conf |  30 --
 .../generic/GenericObjectMapperProvider.java    |   2 +
 eagle-core/eagle-query/pom.xml                  |   1 -
 eagle-core/pom.xml                              |   4 +-
 eagle-examples/eagle-app-example/pom.xml        |  52 ++++
 .../eagle/app/example/ExampleApplication.java   |  30 ++
 .../app/example/ExampleApplicationProvider.java |  63 ++++
 .../example/ExampleApplicationProvider2.java    |  33 ++
 .../eagle/app/example/RandomEventSpout.java     |  59 ++++
 .../main/resources/ExampleApplicationConf.xml   |  31 ++
 .../resources/ExampleApplicationMetadata.xml    | 101 +++++++
 ...org.apache.eagle.app.spi.ApplicationProvider |  17 ++
 .../src/main/webapp/app/apps/example/index.html |   6 +
 .../src/main/webapp/package.json                |   0
 .../app/example/ExampleApplicationTest.java     |  91 ++++++
 eagle-examples/pom.xml                          |   1 +
 .../security/service/InMemMetadataDaoImpl.java  |   3 +
 eagle-server/pom.xml                            | 143 +++++++++
 .../eagle/server/RESTExceptionMapper.java       |  62 ++++
 .../apache/eagle/server/ServerApplication.java  |  80 +++++
 .../org/apache/eagle/server/ServerConfig.java   |  52 ++++
 .../org/apache/eagle/server/ServerMain.java     |  23 ++
 .../src/main/resources/application.conf         |  57 ++++
 .../src/main/resources/log4j.properties         |  21 ++
 eagle-server/src/main/resources/providers.xml   |  27 ++
 eagle-server/src/main/webapp/app/index.html     |  19 ++
 eagle-server/src/main/webapp/package.json       |   0
 .../eagle/server/ServerApplicationTest.java     |  26 ++
 .../pwdgen/PasswordEncoderGenerator.java        |   2 +-
 pom.xml                                         |  51 +++-
 263 files changed, 12206 insertions(+), 6123 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-alert-parent/eagle-alert/alert-common/src/main/java/org/apache/eagle/alert/engine/coordinator/StreamColumn.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-alert-parent/eagle-alert/alert-common/src/main/java/org/apache/eagle/alert/engine/coordinator/StreamColumn.java b/eagle-core/eagle-alert-parent/eagle-alert/alert-common/src/main/java/org/apache/eagle/alert/engine/coordinator/StreamColumn.java
index bbfb942..b11729d 100644
--- a/eagle-core/eagle-alert-parent/eagle-alert/alert-common/src/main/java/org/apache/eagle/alert/engine/coordinator/StreamColumn.java
+++ b/eagle-core/eagle-alert-parent/eagle-alert/alert-common/src/main/java/org/apache/eagle/alert/engine/coordinator/StreamColumn.java
@@ -16,7 +16,14 @@
  */
 package org.apache.eagle.alert.engine.coordinator;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import java.io.IOException;
 import java.io.Serializable;
+import java.util.HashMap;
 
 
 public class StreamColumn implements Serializable {
@@ -40,6 +47,7 @@ public class StreamColumn implements Serializable {
         this.name = name;
     }
 
+    @XmlJavaTypeAdapter(StreamColumnTypeAdapter.class)
     public Type getType() {
         return type;
     }
@@ -48,12 +56,43 @@ public class StreamColumn implements Serializable {
         this.type = type;
     }
 
+    @XmlJavaTypeAdapter(value = DefaultValueAdapter.class)
     public Object getDefaultValue() {
         return defaultValue;
     }
 
+    private void ensureDefaultValueType() {
+        if(this.getDefaultValue()!=null && (this.getDefaultValue() instanceof String) && this.getType() != Type.STRING){
+            switch (this.getType()) {
+                case INT:
+                    this.setDefaultValue(Integer.valueOf((String) this.getDefaultValue()));
+                    break;
+                case LONG:
+                    this.setDefaultValue(Long.valueOf((String) this.getDefaultValue()));
+                    break;
+                case FLOAT:
+                    this.setDefaultValue(Float.valueOf((String) this.getDefaultValue()));
+                    break;
+                case DOUBLE:
+                    this.setDefaultValue(Double.valueOf((String) this.getDefaultValue()));
+                    break;
+                case BOOL:
+                    this.setDefaultValue(Double.valueOf((String) this.getDefaultValue()));
+                    break;
+                case OBJECT:
+                    try {
+                        this.setDefaultValue(new ObjectMapper().readValue((String) this.getDefaultValue(),HashMap.class));
+                    } catch (IOException e) {
+                        throw new IllegalArgumentException(e);
+                    }
+                    break;
+            }
+        }
+    }
+
     public void setDefaultValue(Object defaultValue) {
         this.defaultValue = defaultValue;
+        ensureDefaultValueType();
     }
 
     public boolean isRequired() {
@@ -98,6 +137,31 @@ public class StreamColumn implements Serializable {
         }
     }
 
+    public static class StreamColumnTypeAdapter extends XmlAdapter<String,Type>{
+
+        @Override
+        public Type unmarshal(String v) throws Exception {
+            return Type.getEnumFromValue(v);
+        }
+
+        @Override
+        public String marshal(Type v) throws Exception {
+            return v.name;
+        }
+    }
+
+    public static class DefaultValueAdapter extends XmlAdapter<String,Object>{
+        @Override
+        public Object unmarshal(String v) throws Exception {
+            return v;
+        }
+
+        @Override
+        public String marshal(Object v) throws Exception {
+            return v.toString();
+        }
+    }
+
     public static class Builder {
         private StreamColumn column;
 

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-alert-parent/eagle-alert/alert-common/src/main/java/org/apache/eagle/alert/engine/coordinator/StreamDefinition.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-alert-parent/eagle-alert/alert-common/src/main/java/org/apache/eagle/alert/engine/coordinator/StreamDefinition.java b/eagle-core/eagle-alert-parent/eagle-alert/alert-common/src/main/java/org/apache/eagle/alert/engine/coordinator/StreamDefinition.java
index cd5773a..beb8491 100644
--- a/eagle-core/eagle-alert-parent/eagle-alert/alert-common/src/main/java/org/apache/eagle/alert/engine/coordinator/StreamDefinition.java
+++ b/eagle-core/eagle-alert-parent/eagle-alert/alert-common/src/main/java/org/apache/eagle/alert/engine/coordinator/StreamDefinition.java
@@ -16,6 +16,7 @@
  */
 package org.apache.eagle.alert.engine.coordinator;
 
+import javax.xml.bind.annotation.*;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
@@ -34,7 +35,7 @@ public class StreamDefinition implements Serializable{
     private boolean validate;
     private boolean timeseries;
 
-    private List<StreamColumn> columns = new ArrayList<StreamColumn>();
+    private List<StreamColumn> columns = new ArrayList<>();
 
     public String toString(){
         return String.format("StreamDefinition[streamId=%s, dataSource=%s, description=%s, validate=%s, timeseries=%s, columns=%s",
@@ -78,6 +79,8 @@ public class StreamDefinition implements Serializable{
         this.timeseries = timeseries;
     }
 
+    @XmlElementWrapper(name="columns")
+    @XmlElement(name = "column")
     public List<StreamColumn> getColumns() {
         return columns;
     }

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-alert-parent/eagle-alert/alert-engine/src/test/java/org/apache/eagle/alert/engine/mock/MockSampleMetadataFactory.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-alert-parent/eagle-alert/alert-engine/src/test/java/org/apache/eagle/alert/engine/mock/MockSampleMetadataFactory.java b/eagle-core/eagle-alert-parent/eagle-alert/alert-engine/src/test/java/org/apache/eagle/alert/engine/mock/MockSampleMetadataFactory.java
index 97e6310..22c13a2 100644
--- a/eagle-core/eagle-alert-parent/eagle-alert/alert-engine/src/test/java/org/apache/eagle/alert/engine/mock/MockSampleMetadataFactory.java
+++ b/eagle-core/eagle-alert-parent/eagle-alert/alert-engine/src/test/java/org/apache/eagle/alert/engine/mock/MockSampleMetadataFactory.java
@@ -63,11 +63,6 @@ public class MockSampleMetadataFactory {
         streamColumns.add(new StreamColumn.Builder().name("flag").type(StreamColumn.Type.BOOL).build());
         streamColumns.add(new StreamColumn.Builder().name("timestamp").type(StreamColumn.Type.LONG).build());
         streamColumns.add(new StreamColumn.Builder().name("value").type(StreamColumn.Type.DOUBLE).build());
-//        streamColumns.add(new StreamColumn.Builder().name("value1").type(StreamColumn.Type.DOUBLE).build());
-//        streamColumns.add(new StreamColumn.Builder().name("value2").type(StreamColumn.Type.DOUBLE).build());
-//        streamColumns.add(new StreamColumn.Builder().name("value3").type(StreamColumn.Type.DOUBLE).build());
-//        streamColumns.add(new StreamColumn.Builder().name("value4").type(StreamColumn.Type.DOUBLE).build());
-//        streamColumns.add(new StreamColumn.Builder().name("value5").type(StreamColumn.Type.DOUBLE).build());
         sampleStreamDefinition.setColumns(streamColumns);
         return sampleStreamDefinition;
     }

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata-service/src/main/java/org/apache/eagle/service/metadata/resource/MetadataResource.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata-service/src/main/java/org/apache/eagle/service/metadata/resource/MetadataResource.java b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata-service/src/main/java/org/apache/eagle/service/metadata/resource/MetadataResource.java
index 7e4dea7..8712241 100644
--- a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata-service/src/main/java/org/apache/eagle/service/metadata/resource/MetadataResource.java
+++ b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata-service/src/main/java/org/apache/eagle/service/metadata/resource/MetadataResource.java
@@ -27,6 +27,7 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 
+import com.google.inject.Inject;
 import org.apache.eagle.alert.coordination.model.Kafka2TupleMetadata;
 import org.apache.eagle.alert.coordination.model.ScheduleState;
 import org.apache.eagle.alert.coordination.model.internal.PolicyAssignment;
@@ -36,8 +37,8 @@ import org.apache.eagle.alert.engine.coordinator.Publishment;
 import org.apache.eagle.alert.engine.coordinator.PublishmentType;
 import org.apache.eagle.alert.engine.coordinator.StreamDefinition;
 import org.apache.eagle.alert.engine.coordinator.StreamingCluster;
-import org.apache.eagle.alert.metadata.impl.MetadataDaoFactory;
 import org.apache.eagle.alert.metadata.IMetadataDao;
+import org.apache.eagle.alert.metadata.impl.MetadataDaoFactory;
 import org.apache.eagle.alert.metadata.resource.Models;
 import org.apache.eagle.alert.metadata.resource.OpResult;
 
@@ -50,7 +51,13 @@ import org.apache.eagle.alert.metadata.resource.OpResult;
 @Consumes("application/json")
 public class MetadataResource {
 
-    private IMetadataDao dao = MetadataDaoFactory.getInstance().getMetadataDao();
+//    private IMetadataDao dao = MetadataDaoFactory.getInstance().getMetadataDao();
+    private final IMetadataDao dao;
+
+    @Inject
+    public MetadataResource(IMetadataDao dao){
+        this.dao = dao;
+    }
 
     @Path("/clusters")
     @GET

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/pom.xml
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/pom.xml b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/pom.xml
index 7b789ab..1c0506b 100644
--- a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/pom.xml
+++ b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/pom.xml
@@ -58,5 +58,10 @@
 			<version>1.50.5</version>
 			<scope>test</scope>
 		</dependency>
+		<dependency>
+			<groupId>com.google.inject</groupId>
+			<artifactId>guice</artifactId>
+			<version>3.0</version>
+		</dependency>
 	</dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/InMemMetadataDaoImpl.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/InMemMetadataDaoImpl.java b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/InMemMetadataDaoImpl.java
index fc1bbaa..ecd9a6e 100644
--- a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/InMemMetadataDaoImpl.java
+++ b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/InMemMetadataDaoImpl.java
@@ -25,6 +25,7 @@ import java.util.SortedMap;
 import java.util.TreeMap;
 import java.util.function.Predicate;
 
+import com.google.inject.Inject;
 import org.apache.eagle.alert.coordination.model.Kafka2TupleMetadata;
 import org.apache.eagle.alert.coordination.model.ScheduleState;
 import org.apache.eagle.alert.coordination.model.internal.PolicyAssignment;
@@ -64,7 +65,8 @@ public class InMemMetadataDaoImpl implements IMetadataDao {
     private SortedMap<String, ScheduleState> scheduleStates = new TreeMap<String, ScheduleState>();
     private List<PolicyAssignment> assignments = new ArrayList<PolicyAssignment>();
     private List<Topology> topologies = new ArrayList<Topology>();
-    
+
+    @Inject
     public InMemMetadataDaoImpl(Config config) {
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/JdbcDatabaseHandler.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/JdbcDatabaseHandler.java b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/JdbcDatabaseHandler.java
index a5448a4..08d670a 100644
--- a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/JdbcDatabaseHandler.java
+++ b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/JdbcDatabaseHandler.java
@@ -98,17 +98,19 @@ public class JdbcDatabaseHandler {
             LOG.info("update {} entities", status);
             connection.commit();
         } catch (SQLException e) {
-            //e.printStackTrace();
+            LOG.error(e.getMessage(),e.getCause());
             if(e.getMessage().toLowerCase().contains("duplicate")){
+                LOG.info("Detected duplicated entity");
                 try {
                     connection.rollback(savepoint);
                     update(tb, key, value);
                 } catch (SQLException e1) {
                     //e1.printStackTrace();
-                    LOG.warn("Rollback failed");
+                    LOG.warn("Rollback failed",e1);
                 }
             }
         } catch (JsonProcessingException e) {
+            LOG.error("Got JsonProcessingException: {}",e.getMessage(),e.getCause());
             result.code = OpResult.FAILURE;
             result.message = e.getMessage();
         } finally {
@@ -116,7 +118,7 @@ public class JdbcDatabaseHandler {
                 try {
                     statement.close();
                 } catch (SQLException e) {
-                    e.printStackTrace();
+                    LOG.error("Failed to close statement: {}",e.getMessage(),e.getCause());
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/JdbcMetadataDaoImpl.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/JdbcMetadataDaoImpl.java b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/JdbcMetadataDaoImpl.java
index 6233938..639edd6 100644
--- a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/JdbcMetadataDaoImpl.java
+++ b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/JdbcMetadataDaoImpl.java
@@ -19,6 +19,7 @@ package org.apache.eagle.alert.metadata.impl;
 import java.io.IOException;
 import java.util.List;
 
+import com.google.inject.Inject;
 import com.typesafe.config.Config;
 import org.apache.eagle.alert.coordination.model.Kafka2TupleMetadata;
 import org.apache.eagle.alert.coordination.model.ScheduleState;
@@ -40,6 +41,7 @@ import org.apache.eagle.alert.metadata.resource.Models;
 public class JdbcMetadataDaoImpl implements IMetadataDao {
     private JdbcDatabaseHandler handler;
 
+    @Inject
     public JdbcMetadataDaoImpl(Config config) {
         handler = new JdbcDatabaseHandler(config);
     }

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/MongoMetadataDaoImpl.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/MongoMetadataDaoImpl.java b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/MongoMetadataDaoImpl.java
index 4e2beab..a990b13 100644
--- a/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/MongoMetadataDaoImpl.java
+++ b/eagle-core/eagle-alert-parent/eagle-alert/alert-metadata-parent/alert-metadata/src/main/java/org/apache/eagle/alert/metadata/impl/MongoMetadataDaoImpl.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.util.LinkedList;
 import java.util.List;
 
+import com.google.inject.Inject;
 import org.apache.eagle.alert.coordination.model.Kafka2TupleMetadata;
 import org.apache.eagle.alert.coordination.model.ScheduleState;
 import org.apache.eagle.alert.coordination.model.internal.PolicyAssignment;
@@ -80,6 +81,7 @@ public class MongoMetadataDaoImpl implements IMetadataDao {
     private MongoCollection<Document> assignments;
     private MongoCollection<Document> topologies;
 
+    @Inject
     public MongoMetadataDaoImpl(Config config) {
         this.connection = config.getString("connection");
         this.client = new MongoClient(new MongoClientURI(this.connection));

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-alert-parent/eagle-alert/alert-service/src/main/java/org/apache/eagle/service/app/ServiceApp.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-alert-parent/eagle-alert/alert-service/src/main/java/org/apache/eagle/service/app/ServiceApp.java b/eagle-core/eagle-alert-parent/eagle-alert/alert-service/src/main/java/org/apache/eagle/service/app/ServiceApp.java
index e4c1a42..8e6fa88 100644
--- a/eagle-core/eagle-alert-parent/eagle-alert/alert-service/src/main/java/org/apache/eagle/service/app/ServiceApp.java
+++ b/eagle-core/eagle-alert-parent/eagle-alert/alert-service/src/main/java/org/apache/eagle/service/app/ServiceApp.java
@@ -66,11 +66,8 @@ public class ServiceApp extends Application<AlertDropWizardConfiguration> {
         environment.getApplicationContext().setContextPath("/rest");
         environment.getObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
 
-        MetadataResource resource = new MetadataResource();
-        environment.jersey().register(resource);
-
-        CoordinatorResource coorResource = new CoordinatorResource();
-        environment.jersey().register(coorResource);
+        environment.jersey().register(MetadataResource.class);
+        environment.jersey().register(CoordinatorResource.class);
 
         // swagger resources
         environment.jersey().register(new ApiListingResource());

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-alert-parent/eagle-alert/pom.xml
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-alert-parent/eagle-alert/pom.xml b/eagle-core/eagle-alert-parent/eagle-alert/pom.xml
index 4c143ec..af6193d 100644
--- a/eagle-core/eagle-alert-parent/eagle-alert/pom.xml
+++ b/eagle-core/eagle-alert-parent/eagle-alert/pom.xml
@@ -291,42 +291,6 @@
 				<artifactId>commons-cli</artifactId>
 				<version>${common.cli.version}</version>
 			</dependency>
-
-			<!-- dropwizard -->
-		    <dependency>
-		        <groupId>io.dropwizard</groupId>
-		        <artifactId>dropwizard-core</artifactId>
-		        <version>${dropwizard.version}</version>
-		        <exclusions>
-			        <exclusion>
-						<groupId>org.slf4j</groupId>
-						<artifactId>slf4j-log4j12</artifactId>
-					</exclusion>
-		        </exclusions>
-		    </dependency>
-		    <dependency>
-		        <groupId>io.dropwizard</groupId>
-		        <artifactId>dropwizard-jersey</artifactId>
-		        <version>${dropwizard.version}</version>
-		        <exclusions>
-			        <exclusion>
-						<groupId>org.slf4j</groupId>
-						<artifactId>slf4j-log4j12</artifactId>
-					</exclusion>
-		        </exclusions>
-		    </dependency>
-		    <dependency>
-				<groupId>io.swagger</groupId>
-				<artifactId>swagger-jersey-jaxrs</artifactId>
-				<version>${swagger.version}</version>
-				<scope>compile</scope>
-				<exclusions>
-					<exclusion>
-						<groupId>com.sun.jersey</groupId>
-						<artifactId>*</artifactId>
-					</exclusion>
-				</exclusions>
-			</dependency>
 		</dependencies>
 	</dependencyManagement>
 

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/pom.xml
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/pom.xml b/eagle-core/eagle-app/eagle-app-base/pom.xml
new file mode 100644
index 0000000..500db86
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>eagle-app-parent</artifactId>
+        <groupId>org.apache.eagle</groupId>
+        <version>0.5.0-incubating-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>eagle-app-base</artifactId>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <version>${guice.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe</groupId>
+            <artifactId>config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject.extensions</groupId>
+            <artifactId>guice-servlet</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>jsr311-api</artifactId>
+            <version>1.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.eagle</groupId>
+            <artifactId>alert-metadata</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>xerces</groupId>
+                    <artifactId>xercesImpl</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-server</artifactId>
+            <version>${jersey.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.eagle</groupId>
+            <artifactId>eagle-metadata-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.eagle</groupId>
+            <artifactId>eagle-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.eagle</groupId>
+            <artifactId>eagle-metadata-base</artifactId>
+            <version>0.5.0-incubating-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/AbstractApplication.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/AbstractApplication.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/AbstractApplication.java
new file mode 100644
index 0000000..1cb2625
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/AbstractApplication.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.eagle.app;
+
+import backtype.storm.Config;
+import backtype.storm.LocalCluster;
+import backtype.storm.StormSubmitter;
+import backtype.storm.generated.*;
+import backtype.storm.topology.TopologyBuilder;
+import backtype.storm.utils.NimbusClient;
+import org.apache.eagle.metadata.model.ApplicationEntity;
+import org.apache.thrift7.TException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import scala.Int;
+import storm.trident.spout.RichSpoutBatchExecutor;
+
+import java.io.Serializable;
+
+public abstract class AbstractApplication implements Application,Serializable {
+    private final static Logger LOG = LoggerFactory.getLogger(AbstractApplication.class);
+    private static LocalCluster _localCluster;
+
+    static {
+        Runtime.getRuntime().addShutdownHook(new Thread(){
+            @Override
+            public void run() {
+                if(_localCluster != null) {
+                    LOG.info("Shutting down local storm cluster instance");
+                    _localCluster.shutdown();
+                }
+            }
+        });
+    }
+
+    private static LocalCluster getLocalCluster(){
+        if(_localCluster == null){
+            _localCluster = new LocalCluster();
+        }
+
+        return _localCluster;
+    }
+
+    @Override
+    public void start(ApplicationContext context){
+        ApplicationEntity appEntity = context.getAppEntity();
+        String topologyName = context.getAppEntity().getAppId();
+
+        TopologyBuilder builder = new TopologyBuilder();
+        buildTopology(builder,context);
+        StormTopology topology = builder.createTopology();
+        Config conf = getClusterStormConfig(context);
+        if(appEntity.getMode() == ApplicationEntity.Mode.CLUSTER){
+            String jarFile = context.getAppEntity().getDescriptor().getJarPath();
+            synchronized (AbstractApplication.class) {
+                System.setProperty("storm.jar", jarFile);
+                LOG.info("Submitting as cluster mode");
+                try {
+                    StormSubmitter.submitTopologyWithProgressBar(topologyName, conf, topology);
+                } catch (AlreadyAliveException | InvalidTopologyException e) {
+                    LOG.error(e.getMessage(), e);
+                    throw new RuntimeException(e.getMessage(),e);
+                } finally {
+                    System.clearProperty("storm.jar");
+                }
+            }
+        }else{
+            LOG.info("Submitting as local mode");
+            getLocalCluster().submitTopology(topologyName, conf, topology);
+        }
+    }
+
+    private final static String STORM_NIMBUS_HOST_CONF_PATH = "application.storm.nimbusHost";
+    private final static String STORM_NIMBUS_HOST_DEFAULT = "localhost";
+    private final static Integer STORM_NIMBUS_THRIFT_DEFAULT = 6627;
+    private final static String STORM_NIMBUS_THRIFT_CONF_PATH = "application.storm.nimbusThriftPort";
+
+    private static Config getClusterStormConfig(ApplicationContext context){
+        Config conf = new Config();
+        conf.put(RichSpoutBatchExecutor.MAX_BATCH_SIZE_CONF, Int.box(64 * 1024));
+        conf.put(Config.TOPOLOGY_RECEIVER_BUFFER_SIZE, Int.box(8));
+        conf.put(Config.TOPOLOGY_TRANSFER_BUFFER_SIZE, Int.box(32));
+        conf.put(Config.TOPOLOGY_EXECUTOR_RECEIVE_BUFFER_SIZE, Int.box(16384));
+        conf.put(Config.TOPOLOGY_EXECUTOR_SEND_BUFFER_SIZE, Int.box(16384));
+        conf.put(Config.NIMBUS_THRIFT_MAX_BUFFER_SIZE, Int.box(20480000));
+        String nimbusHost = STORM_NIMBUS_HOST_DEFAULT;
+
+        if(context.getEnvConfig().hasPath(STORM_NIMBUS_HOST_CONF_PATH)) {
+            nimbusHost = context.getEnvConfig().getString(STORM_NIMBUS_HOST_CONF_PATH);
+            LOG.info("Overriding {} = {}",STORM_NIMBUS_HOST_CONF_PATH,nimbusHost);
+        } else {
+            LOG.info("Using default {} = {}",STORM_NIMBUS_HOST_CONF_PATH,STORM_NIMBUS_HOST_DEFAULT);
+        }
+        Integer nimbusThriftPort =  STORM_NIMBUS_THRIFT_DEFAULT;
+        if(context.getEnvConfig().hasPath(STORM_NIMBUS_THRIFT_CONF_PATH)) {
+            nimbusThriftPort = context.getEnvConfig().getInt(STORM_NIMBUS_THRIFT_CONF_PATH);
+            LOG.info("Overriding {} = {}",STORM_NIMBUS_THRIFT_CONF_PATH,nimbusThriftPort);
+        } else {
+            LOG.info("Using default {} = {}",STORM_NIMBUS_THRIFT_CONF_PATH,STORM_NIMBUS_THRIFT_DEFAULT);
+        }
+        conf.put(backtype.storm.Config.NIMBUS_HOST, nimbusHost);
+        conf.put(backtype.storm.Config.NIMBUS_THRIFT_PORT, nimbusThriftPort);
+        return conf;
+    }
+
+    protected abstract void buildTopology(TopologyBuilder builder, ApplicationContext context);
+
+    @Override
+    public void stop(ApplicationContext context) {
+        ApplicationEntity appEntity = context.getAppEntity();
+        String appId = appEntity.getAppId();
+        if(appEntity.getMode() == ApplicationEntity.Mode.CLUSTER){
+            Nimbus.Client stormClient = NimbusClient.getConfiguredClient(getClusterStormConfig(context)).getClient();
+            try {
+                stormClient.killTopology(appId);
+            } catch (NotAliveException | TException e) {
+                LOG.error("Failed to kill topology named {}, due to: {}",appId,e.getMessage(),e.getCause());
+            }
+        } else {
+            getLocalCluster().killTopology(appId);
+        }
+    }
+
+    @Override
+    public void status(ApplicationContext context) {
+        // TODO: Not implemented yet!
+        throw new RuntimeException("TODO: Not implemented yet!");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/Application.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/Application.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/Application.java
new file mode 100644
index 0000000..ffe5339
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/Application.java
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.eagle.app;
+
+/**
+ * Application Lifecycle Interface
+ */
+public interface Application {
+    /**
+     *
+     * @param context
+     */
+    void start(ApplicationContext context);
+
+    /**
+     *
+     * @param context
+     */
+    void stop(ApplicationContext context);
+
+    /**
+     * 
+     * @param context
+     */
+    void status(ApplicationContext context);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ApplicationContext.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ApplicationContext.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ApplicationContext.java
new file mode 100644
index 0000000..1723250
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ApplicationContext.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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.eagle.app;
+
+import com.typesafe.config.Config;
+import org.apache.eagle.alert.engine.coordinator.StreamDefinition;
+import org.apache.eagle.app.sink.StreamSink;
+import org.apache.eagle.metadata.model.ApplicationEntity;
+import org.apache.eagle.metadata.model.StreamDesc;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Application Execution Context
+ */
+public class ApplicationContext implements Serializable {
+    private final Config envConfig;
+    private final ApplicationEntity appEntity;
+    private final static Logger LOG = LoggerFactory.getLogger(ApplicationContext.class);
+    private final Map<String, StreamSink> streamSinkMap;
+    private final Map<String,StreamDesc> streamDescMap;
+
+    public ApplicationContext(ApplicationEntity appEntity, Config envConfig){
+        this.appEntity = appEntity;
+        this.envConfig = envConfig;
+        this.streamSinkMap = new HashMap<>();
+        this.streamDescMap = new HashMap<>();
+
+        // TODO: Decouple out of ApplicationContext constructor
+        doInit();
+    }
+
+    private void doInit() {
+        try {
+            Class<?> sinkClass = appEntity.getDescriptor().getSinkClass();
+            List<StreamDefinition> outputStreams = appEntity.getDescriptor().getStreams();
+            if(null != outputStreams){
+                Constructor constructor = sinkClass.getConstructor(StreamDefinition.class,ApplicationContext.class);
+                outputStreams.forEach((stream) -> {
+                    try {
+                        StreamSink streamSink = (StreamSink) constructor.newInstance(stream,this);
+                        streamSinkMap.put(stream.getStreamId(), streamSink);
+                        StreamDesc streamDesc = new StreamDesc();
+                        streamDesc.setStreamSchema(stream);
+                        streamDesc.setSinkContext(streamSink.getSinkContext());
+                        streamDesc.setSinkType(sinkClass);
+                        streamDesc.setStreamId(stream.getStreamId());
+                        streamDescMap.put(streamDesc.getStreamId(),streamDesc);
+                    } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
+                        LOG.error("Failed to initialize instance "+sinkClass.getCanonicalName()+" for application: {}",this.getAppEntity());
+                        throw new RuntimeException("Failed to initialize instance "+sinkClass.getCanonicalName()+" for application:"+this.getAppEntity(),e);
+                    }
+                });
+            }
+        } catch (NoSuchMethodException e) {
+            LOG.error(e.getMessage(),e);
+            throw new RuntimeException(e.getMessage(),e.getCause());
+        }
+    }
+
+    public ApplicationEntity getAppEntity() {
+        return appEntity;
+    }
+
+    public Config getEnvConfig() {
+        return envConfig;
+    }
+
+    /**
+     * Make sure streamId is declared in Application Providers
+     *
+     * @param streamId
+     * @return
+     */
+    public StreamSink getStreamSink(String streamId){
+        if(streamSinkMap.containsKey(streamId)) {
+            return streamSinkMap.get(streamId);
+        } else {
+            throw new IllegalStateException("Stream (ID: "+streamId+") was not declared in "+this.appEntity.getDescriptor().getProviderClass().getCanonicalName()+" before being called");
+        }
+    }
+
+    public Collection<StreamDesc> getStreamSinkDescs(){
+        return streamDescMap.values();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ApplicationGuiceModule.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ApplicationGuiceModule.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ApplicationGuiceModule.java
new file mode 100644
index 0000000..9a66b6c
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ApplicationGuiceModule.java
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.eagle.app;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Singleton;
+import org.apache.eagle.app.service.ApplicationManagementService;
+import org.apache.eagle.app.service.ApplicationManagementServiceImpl;
+import org.apache.eagle.app.service.ApplicationProviderService;
+import org.apache.eagle.app.service.ApplicationProviderServiceImpl;
+import org.apache.eagle.metadata.service.ApplicationDescService;
+
+
+public class ApplicationGuiceModule extends AbstractModule {
+    @Override
+    protected void configure() {
+        bind(ApplicationProviderServiceImpl.class).in(Singleton.class);
+        bind(ApplicationProviderService.class).to(ApplicationProviderServiceImpl.class).in(Singleton.class);
+        bind(ApplicationDescService.class).to(ApplicationProviderServiceImpl.class).in(Singleton.class);
+        bind(ApplicationManagementService.class).to(ApplicationManagementServiceImpl.class).in(Singleton.class);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProviderConfig.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProviderConfig.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProviderConfig.java
new file mode 100644
index 0000000..e3cd9e7
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProviderConfig.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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.eagle.app.config;
+
+import org.apache.eagle.app.spi.ApplicationProvider;
+
+public class ApplicationProviderConfig {
+    private String jarPath;
+    private String className;
+
+    public ApplicationProviderConfig(){}
+    public ApplicationProviderConfig(String jarPath, Class<? extends ApplicationProvider> className){
+        this.jarPath = jarPath;
+        this.className = className.getCanonicalName();
+    }
+    public ApplicationProviderConfig(String jarPath, String className){
+        this.jarPath = jarPath;
+        this.className = className;
+    }
+    @Override
+    public String toString() {
+        return String.format("ApplicationProviderConfig[jarPath=%s,className=%s]",this.getJarPath(),this.getClassName());
+    }
+
+    public String getJarPath() {
+        return jarPath;
+    }
+
+    public void setJarPath(String jarPath) {
+        this.jarPath = jarPath;
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public void setClassName(String className) {
+        this.className = className;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProviderDescConfig.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProviderDescConfig.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProviderDescConfig.java
new file mode 100644
index 0000000..1fbae16
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProviderDescConfig.java
@@ -0,0 +1,147 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.eagle.app.config;
+
+
+import org.apache.eagle.alert.engine.coordinator.StreamDefinition;
+import org.apache.eagle.metadata.model.ApplicationDocs;
+import org.apache.eagle.metadata.model.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.*;
+import java.io.InputStream;
+import java.util.List;
+
+@XmlRootElement(name = "application")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ApplicationProviderDescConfig {
+    private String type;
+    private String name;
+    private String version;
+    private String description;
+    private String appClass;
+    private String viewPath;
+    private Configuration configuration;
+    private ApplicationDocs docs;
+
+    @XmlElementWrapper(name="streams")
+    @XmlElement(name = "stream")
+    private List<StreamDefinition> streams;
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public Configuration getConfiguration() {
+        return configuration;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getViewPath() {
+        return viewPath;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public void setViewPath(String viewPath) {
+        this.viewPath = viewPath;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("ApplicationDesc [type=%s, name=%s, version=%s, appClass=%s, viewPath=%s, configuration= %s properties, description=%s",
+                getType(),getName(),getVersion(),getAppClass(), getViewPath(), getConfiguration() == null ? 0: getConfiguration().size(),getDescription());
+    }
+
+    public void setConfiguration(Configuration configuration) {
+        this.configuration = configuration;
+    }
+
+
+    public List<StreamDefinition> getStreams() {
+        return streams;
+    }
+
+    public void setStreams(List<StreamDefinition> streams) {
+        this.streams = streams;
+    }
+
+    private final static Logger LOG = LoggerFactory.getLogger(ApplicationProviderDescConfig.class);
+
+    public static ApplicationProviderDescConfig loadFromXML(String configXmlFile){
+        try {
+            JAXBContext jc = JAXBContext.newInstance(ApplicationProviderDescConfig.class);
+            Unmarshaller unmarshaller = jc.createUnmarshaller();
+            InputStream is = ApplicationProviderDescConfig.class.getResourceAsStream(configXmlFile);
+            if(is == null){
+                is = ApplicationProviderDescConfig.class.getResourceAsStream("/"+configXmlFile);
+            }
+            if(is == null){
+                LOG.error("Application descriptor configuration {} is not found",configXmlFile);
+                throw new IllegalStateException("Application descriptor configuration "+configXmlFile+" is not found");
+            }
+            return (ApplicationProviderDescConfig) unmarshaller.unmarshal(is);
+        }catch (Exception ex){
+            LOG.error("Failed to load application descriptor configuration: {}",configXmlFile,ex);
+            throw new RuntimeException("Failed to load application descriptor configuration: "+configXmlFile,ex);
+        }
+    }
+
+    public String getAppClass() {
+        return appClass;
+    }
+
+    public void setAppClass(String appClass) {
+        this.appClass = appClass;
+    }
+
+    public ApplicationDocs getDocs() {
+        return docs;
+    }
+
+    public void setDocs(ApplicationDocs docs) {
+        this.docs = docs;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProvidersConfig.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProvidersConfig.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProvidersConfig.java
new file mode 100644
index 0000000..f5aaa9f
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/config/ApplicationProvidersConfig.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.eagle.app.config;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.List;
+
+@XmlRootElement(name = "providers")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ApplicationProvidersConfig {
+
+    @XmlElement(name = "provider")
+    private List<ApplicationProviderConfig> providers;
+
+    public List<ApplicationProviderConfig> getProviders() {
+        return providers;
+    }
+
+    public void setProviders(List<ApplicationProviderConfig> providers) {
+        this.providers = providers;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/resource/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/resource/ApplicationResource.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/resource/ApplicationResource.java
new file mode 100644
index 0000000..a0654ff
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/resource/ApplicationResource.java
@@ -0,0 +1,155 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.eagle.app.resource;
+
+
+import com.google.inject.Inject;
+import org.apache.eagle.app.service.ApplicationManagementService;
+import org.apache.eagle.app.service.AppOperations;
+import org.apache.eagle.app.service.ApplicationProviderService;
+import org.apache.eagle.metadata.model.ApplicationDesc;
+import org.apache.eagle.metadata.model.ApplicationEntity;
+import org.apache.eagle.metadata.service.ApplicationEntityService;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import java.util.Collection;
+
+@Path("/apps")
+public class ApplicationResource {
+    private final ApplicationProviderService providerService;
+    private final ApplicationManagementService applicationManagementService;
+    private final ApplicationEntityService entityService;
+
+    @Inject
+    public ApplicationResource(
+            ApplicationProviderService providerService,
+            ApplicationManagementService applicationManagementService,
+            ApplicationEntityService entityService){
+        this.providerService = providerService;
+        this.applicationManagementService = applicationManagementService;
+        this.entityService = entityService;
+    }
+
+    @GET
+    @Path("/providers")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Collection<ApplicationDesc> getApplicationDescs(){
+        return providerService.getApplicationDescs();
+    }
+
+    @GET
+    @Path("/providers/{type}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public ApplicationDesc getApplicationDescs(@PathParam("type") String type){
+        return providerService.getApplicationDescByType(type);
+    }
+
+    @POST
+    @Path("/providers/reload")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Collection<ApplicationDesc> reloadApplicationDescs(){
+        providerService.reload();
+        return providerService.getApplicationDescs();
+    }
+
+    @GET
+    @Path("/")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Collection<ApplicationEntity> getApplicationEntities(@QueryParam("siteId") String siteId){
+        if(siteId == null) {
+            return entityService.findAll();
+        } else {
+            return entityService.findBySiteId(siteId);
+        }
+    }
+
+    @GET
+    @Path("/{appUuid}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public ApplicationEntity getApplicationEntityByUUID(@PathParam("appUuid") String appUuid){
+        return entityService.getByUUID(appUuid);
+    }
+
+    /**
+     * <b>Request:</b>
+     * <pre>
+     * {
+     *      uuid: APPLICATION_UUID
+     * }
+     * </pre>
+     */
+    @POST
+    @Path("/install")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public ApplicationEntity installApplication(AppOperations.InstallOperation operation){
+        return applicationManagementService.install(operation);
+    }
+
+    /**
+     * <b>Request:</b>
+     * <pre>
+     * {
+     *      uuid: APPLICATION_UUID
+     * }
+     * </pre>
+     *
+     * @param operation
+     */
+    @POST
+    @Path("/uninstall")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public ApplicationEntity uninstallApplication(AppOperations.UninstallOperation operation){
+        return applicationManagementService.uninstall(operation);
+    }
+
+    /**
+     * <b>Request:</b>
+     * <pre>
+     * {
+     *      uuid: APPLICATION_UUID
+     * }
+     *operation
+     * @param operation
+     */
+    @POST
+    @Path("/start")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public ApplicationEntity startApplication(AppOperations.StartOperation operation){
+        return applicationManagementService.start(operation);
+    }
+
+    /**
+     * <b>Request:</b>
+     * <pre>
+     * {
+     *      uuid: APPLICATION_UUID
+     * }
+     * </pre>
+     * @param operation
+     */
+    @POST
+    @Path("/stop")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public ApplicationEntity stopApplication(AppOperations.StopOperation operation){
+        return applicationManagementService.stop(operation);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/AppOperations.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/AppOperations.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/AppOperations.java
new file mode 100644
index 0000000..f2395d6
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/AppOperations.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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.eagle.app.service;
+
+import org.apache.eagle.metadata.model.ApplicationEntity;
+
+import java.io.Serializable;
+import java.util.Map;
+
+public class AppOperations {
+    interface Operation extends Serializable {
+        //
+    }
+
+    public static class InstallOperation implements Operation{
+        private String siteId;
+        private String appType;
+        private ApplicationEntity.Mode mode = ApplicationEntity.Mode.LOCAL;
+        private Map<String,Object> configuration;
+
+        public InstallOperation(){}
+        public InstallOperation(String siteId,String appType){
+            this.setSiteId(siteId);
+            this.setAppType(appType);
+        }
+        public InstallOperation(String siteId,String appType,ApplicationEntity.Mode mode){
+            this.setSiteId(siteId);
+            this.setAppType(appType);
+            this.setMode(mode);
+        }
+        public InstallOperation(String siteId,String appType,ApplicationEntity.Mode mode,Map<String,Object> configuration){
+            this.setSiteId(siteId);
+            this.setAppType(appType);
+            this.setMode(mode);
+            this.setConfiguration(configuration);
+        }
+
+        public String getSiteId() {
+           return siteId;
+       }
+        public void setSiteId(String siteId) {
+           this.siteId = siteId;
+       }
+        public String getAppType() {
+           return appType;
+       }
+        public void setAppType(String appType) {
+           this.appType = appType;
+       }
+
+        public Map<String, Object> getConfiguration() {
+            return configuration;
+        }
+
+        public void setConfiguration(Map<String, Object> configuration) {
+            this.configuration = configuration;
+        }
+
+        public ApplicationEntity.Mode getMode() {
+            return mode;
+        }
+
+        public void setMode(ApplicationEntity.Mode mode) {
+            this.mode = mode;
+        }
+    }
+
+    public static class UninstallOperation implements Operation{
+        private String uuid;
+        private String appId;
+        public UninstallOperation(String uuid){
+            this.setUuid(uuid);
+        }
+        public UninstallOperation(String uuid,String appId){
+            this.setUuid(uuid);
+            this.setAppId(appId);
+        }
+
+        public String getUuid() {
+            return uuid;
+        }
+        public void setUuid(String uuid) {
+            this.uuid = uuid;
+        }
+
+        public String getAppId() {
+            return appId;
+        }
+
+        public void setAppId(String appId) {
+            this.appId = appId;
+        }
+    }
+
+    public static class StartOperation implements Operation{
+        private String uuid;
+        private String appId;
+        public StartOperation(String uuid){
+            this.setUuid(uuid);
+        }
+        public StartOperation(String uuid,String appId){
+            this.setUuid(uuid);
+            this.setAppId(appId);
+        }
+        public String getUuid() {
+            return uuid;
+        }
+        public void setUuid(String uuid) {
+            this.uuid = uuid;
+        }
+
+        public String getAppId() {
+            return appId;
+        }
+
+        public void setAppId(String appId) {
+            this.appId = appId;
+        }
+    }
+
+    public static class StopOperation implements Operation{
+        private String uuid;
+        private String appId;
+
+        public StopOperation(String uuid){
+            this.setUuid(uuid);
+        }
+        public StopOperation(String uuid,String appId){
+            this.setUuid(uuid);
+            this.setAppId(appId);
+        }
+        public String getUuid() {
+            return uuid;
+        }
+        public void setUuid(String uuid) {
+            this.uuid = uuid;
+        }
+
+        public String getAppId() {
+            return appId;
+        }
+
+        public void setAppId(String appId) {
+            this.appId = appId;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationManagementService.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationManagementService.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationManagementService.java
new file mode 100644
index 0000000..965a3fa
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationManagementService.java
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.eagle.app.service;
+
+import org.apache.eagle.metadata.model.ApplicationEntity;
+
+public interface ApplicationManagementService {
+    /**
+     *
+     * @param operation
+     * @return
+     */
+    ApplicationEntity install(AppOperations.InstallOperation operation);
+
+    /**
+     *
+     * @param operation
+     * @return
+     */
+    ApplicationEntity uninstall(AppOperations.UninstallOperation operation);
+
+    /**
+     *
+     * @param operation
+     * @return
+     */
+    ApplicationEntity start(AppOperations.StartOperation operation);
+
+    /**
+     *
+     * @param operation
+     * @return
+     */
+    ApplicationEntity stop(AppOperations.StopOperation operation);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/e21b073f/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationManagementServiceImpl.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationManagementServiceImpl.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationManagementServiceImpl.java
new file mode 100644
index 0000000..566fb62
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationManagementServiceImpl.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.eagle.app.service;
+
+import com.google.common.base.Preconditions;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.typesafe.config.Config;
+import org.apache.eagle.app.Application;
+import org.apache.eagle.app.ApplicationContext;
+import org.apache.eagle.metadata.model.ApplicationDesc;
+import org.apache.eagle.metadata.model.ApplicationEntity;
+import org.apache.eagle.metadata.model.SiteEntity;
+import org.apache.eagle.metadata.service.ApplicationEntityService;
+import org.apache.eagle.metadata.service.SiteEntityService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class ApplicationManagementServiceImpl implements ApplicationManagementService {
+    private final SiteEntityService siteEntityService;
+    private final ApplicationProviderService applicationProviderService;
+    private final ApplicationEntityService applicationEntityService;
+    private final Config config;
+    private final static Logger LOGGER = LoggerFactory.getLogger(ApplicationManagementServiceImpl.class);
+
+    @Inject
+    public ApplicationManagementServiceImpl(
+            Config config,
+            SiteEntityService siteEntityService,
+            ApplicationProviderService applicationProviderService,
+            ApplicationEntityService applicationEntityService){
+        this.config = config;
+        this.siteEntityService = siteEntityService;
+        this.applicationProviderService = applicationProviderService;
+        this.applicationEntityService = applicationEntityService;
+    }
+
+    public ApplicationEntity install(AppOperations.InstallOperation operation) {
+        Preconditions.checkNotNull(operation.getSiteId(),"siteId is null");
+        Preconditions.checkNotNull(operation.getAppType(),"appType is null");
+        SiteEntity siteEntity = siteEntityService.getBySiteId(operation.getSiteId());
+        Preconditions.checkNotNull(siteEntity,"Site with ID: "+operation.getSiteId()+" is not found");
+        ApplicationDesc appDesc = applicationProviderService.getApplicationDescByType(operation.getAppType());
+        Preconditions.checkNotNull("Application with TYPE: "+operation.getAppType()+" is not found");
+        ApplicationEntity applicationEntity = new ApplicationEntity();
+        applicationEntity.setDescriptor(appDesc);
+        applicationEntity.setSite(siteEntity);
+        applicationEntity.setConfiguration(operation.getConfiguration());
+        applicationEntity.setMode(operation.getMode());
+        ApplicationContext applicationContext = new ApplicationContext(applicationEntity,config);
+        applicationEntity.setStreams(applicationContext.getStreamSinkDescs());
+        applicationEntityService.create(applicationEntity);
+        return applicationEntity;
+    }
+
+    public ApplicationEntity uninstall(AppOperations.UninstallOperation operation) {
+        ApplicationEntity applicationEntity = applicationEntityService.getByUUIDOrAppId(operation.getUuid(),operation.getAppId());
+        Application application = applicationProviderService.getApplicationProviderByType(applicationEntity.getDescriptor().getType()).getApplication();
+        // TODO: Check status, skip stop if already STOPPED
+        try {
+            application.stop(new ApplicationContext(applicationEntity, this.config));
+        }catch (Throwable throwable){
+            LOGGER.error(throwable.getMessage(),throwable);
+        }
+        return applicationEntityService.delete(applicationEntity);
+    }
+
+    public ApplicationEntity start(AppOperations.StartOperation operation) {
+        ApplicationEntity applicationEntity = applicationEntityService.getByUUIDOrAppId(operation.getUuid(),operation.getAppId());
+        Application application = applicationProviderService.getApplicationProviderByType(applicationEntity.getDescriptor().getType()).getApplication();
+        application.start(new ApplicationContext(applicationEntity,this.config));
+        return applicationEntity;
+    }
+
+    public ApplicationEntity stop(AppOperations.StopOperation operation) {
+        ApplicationEntity applicationEntity = applicationEntityService.getByUUIDOrAppId(operation.getUuid(),operation.getAppId());
+        Application application = applicationProviderService.getApplicationProviderByType(applicationEntity.getDescriptor().getType()).getApplication();
+        application.stop(new ApplicationContext(applicationEntity,this.config));
+        return applicationEntity;
+    }
+}
\ No newline at end of file



Mime
View raw message