eagle-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From h..@apache.org
Subject [1/3] incubator-eagle git commit: [EAGLE-402] Refactor Application Framework to be better managed or deployed standalone
Date Wed, 03 Aug 2016 15:25:25 GMT
Repository: incubator-eagle
Updated Branches:
  refs/heads/develop 30db8ef87 -> 4ad1a4182


http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/storm/MockStormApplication.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/storm/MockStormApplication.java b/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/storm/MockStormApplication.java
new file mode 100644
index 0000000..3db5f20
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/storm/MockStormApplication.java
@@ -0,0 +1,97 @@
+/*
+ * 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.storm;
+
+import backtype.storm.generated.StormTopology;
+import backtype.storm.spout.SpoutOutputCollector;
+import backtype.storm.task.TopologyContext;
+import backtype.storm.topology.OutputFieldsDeclarer;
+import backtype.storm.topology.TopologyBuilder;
+import backtype.storm.topology.base.BaseRichSpout;
+import backtype.storm.tuple.Fields;
+import org.apache.eagle.app.Configuration;
+import org.apache.eagle.app.StormApplication;
+import org.apache.eagle.app.environment.impl.StormEnvironment;
+
+import java.util.Arrays;
+import java.util.Map;
+
+public class MockStormApplication extends StormApplication<MockStormApplication.MockStormConfiguration> {
+    private MockStormConfiguration appConfig;
+
+    @Override
+    public StormTopology execute(MockStormConfiguration config, StormEnvironment environment) {
+        this.setAppConfig(config);
+        TopologyBuilder builder = new TopologyBuilder();
+        builder.setSpout("metric_spout", new RandomEventSpout(), config.getSpoutNum());
+        builder.setBolt("sink_1",environment.getFlattenStreamSink("TEST_STREAM_1",config)).fieldsGrouping("metric_spout",new Fields("metric"));
+        builder.setBolt("sink_2",environment.getFlattenStreamSink("TEST_STREAM_2",config)).fieldsGrouping("metric_spout",new Fields("metric"));
+        return builder.createTopology();
+    }
+
+    public MockStormConfiguration getAppConfig() {
+        return appConfig;
+    }
+
+    private void setAppConfig(MockStormConfiguration appConfig) {
+        this.appConfig = appConfig;
+    }
+
+    /**
+     * TODO: Load configuration from name space in application className
+     * Application Configuration
+     */
+    static class MockStormConfiguration extends Configuration {
+        private int spoutNum = 1;
+        private boolean loaded = false;
+
+        public int getSpoutNum() {
+            return spoutNum;
+        }
+
+        public void setSpoutNum(int spoutNum) {
+            this.spoutNum = spoutNum;
+        }
+
+        public boolean isLoaded() {
+            return loaded;
+        }
+
+        public void setLoaded(boolean loaded) {
+            this.loaded = loaded;
+        }
+    }
+
+    private class RandomEventSpout extends BaseRichSpout {
+        private SpoutOutputCollector _collector;
+        @Override
+        public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
+            _collector = spoutOutputCollector;
+        }
+
+        @Override
+        public void nextTuple() {
+            _collector.emit(Arrays.asList("disk.usage",System.currentTimeMillis(),"host_1",56.7));
+            _collector.emit(Arrays.asList("cpu.usage",System.currentTimeMillis(),"host_2",99.8));
+        }
+
+        @Override
+        public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
+            outputFieldsDeclarer.declare(new Fields("metric","timestamp","source","value"));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/storm/MockStormApplicationTest.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/storm/MockStormApplicationTest.java b/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/storm/MockStormApplicationTest.java
new file mode 100644
index 0000000..77bc113
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/storm/MockStormApplicationTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.storm;
+
+import com.typesafe.config.ConfigFactory;
+import org.apache.eagle.app.environment.impl.StormEnvironment;
+import org.apache.eagle.app.utils.DynamicJarPathFinder;
+import org.apache.eagle.metadata.model.ApplicationEntity;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashMap;
+
+public class MockStormApplicationTest {
+    @Test
+    public void testGetConfigClass(){
+        MockStormApplication mockStormApplication = new MockStormApplication();
+        Assert.assertEquals(MockStormApplication.MockStormConfiguration.class,mockStormApplication.getConfigType());
+    }
+
+    @Test
+    public void testGetConfigFromMap(){
+        MockStormApplication mockStormApplication = new MockStormApplication();
+        mockStormApplication.execute(new HashMap<String,Object>(){
+            {
+                put("spoutNum",1234);
+                put("loaded",true);
+                put("mode", ApplicationEntity.Mode.CLUSTER);
+            }
+        },new StormEnvironment(ConfigFactory.load()));
+        Assert.assertTrue(mockStormApplication.getAppConfig().isLoaded());
+        Assert.assertEquals(1234,mockStormApplication.getAppConfig().getSpoutNum());
+        Assert.assertEquals(ApplicationEntity.Mode.CLUSTER,mockStormApplication.getAppConfig().getMode());
+    }
+
+    @Test
+    public void testGetConfigFromEnvironmentConfigFile(){
+        MockStormApplication mockStormApplication = new MockStormApplication();
+        mockStormApplication.execute(new StormEnvironment(ConfigFactory.load()));
+        Assert.assertTrue(mockStormApplication.getAppConfig().isLoaded());
+        Assert.assertEquals(1234,mockStormApplication.getAppConfig().getSpoutNum());
+        Assert.assertEquals(ApplicationEntity.Mode.LOCAL,mockStormApplication.getAppConfig().getMode());
+    }
+
+    @Test
+    public void testRunApplicationWithSysConfig(){
+        new MockStormApplication().run();
+    }
+
+    @Test
+    public void testRunApplicationWithAppConfig() throws InterruptedException {
+        MockStormApplication.MockStormConfiguration appConfig = new MockStormApplication.MockStormConfiguration();
+        appConfig.setJarPath(DynamicJarPathFinder.findPath(MockStormApplication.class));
+        appConfig.setSiteId("test_site");
+        appConfig.setAppId("test_application_storm_topology");
+        appConfig.setMode(ApplicationEntity.Mode.LOCAL);
+        appConfig.setLoaded(true);
+        appConfig.setSpoutNum(4);
+        new MockStormApplication().run(appConfig);
+        Thread.sleep(Long.MAX_VALUE);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-app/eagle-app-base/src/test/resources/META-INF/services/org.apache.eagle.app.spi.ApplicationProvider
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/test/resources/META-INF/services/org.apache.eagle.app.spi.ApplicationProvider b/eagle-core/eagle-app/eagle-app-base/src/test/resources/META-INF/services/org.apache.eagle.app.spi.ApplicationProvider
index 75096f8..fa18007 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/test/resources/META-INF/services/org.apache.eagle.app.spi.ApplicationProvider
+++ b/eagle-core/eagle-app/eagle-app-base/src/test/resources/META-INF/services/org.apache.eagle.app.spi.ApplicationProvider
@@ -13,4 +13,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-org.apache.eagle.app.TestApplicationImpl$Provider
\ No newline at end of file
+org.apache.eagle.app.TestStormAppImpl$Provider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-app/eagle-app-base/src/test/resources/TestApplicationMetadata.xml
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/test/resources/TestApplicationMetadata.xml b/eagle-core/eagle-app/eagle-app-base/src/test/resources/TestApplicationMetadata.xml
index 4582ed1..df70e69 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/test/resources/TestApplicationMetadata.xml
+++ b/eagle-core/eagle-app/eagle-app-base/src/test/resources/TestApplicationMetadata.xml
@@ -20,7 +20,7 @@
     <type>TEST_APPLICATION</type>
     <name>Test Monitoring Application</name>
     <version>0.5.0-incubating</version>
-    <appClass>org.apache.eagle.app.TestApplicationImpl</appClass>
+    <appClass>org.apache.eagle.app.TestStormAppImpl</appClass>
     <viewPath>/apps/example</viewPath>
     <configuration>
         <property>

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-app/eagle-app-base/src/test/resources/application.conf
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/test/resources/application.conf b/eagle-core/eagle-app/eagle-app-base/src/test/resources/application.conf
index ac0b76c..0daa975 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/test/resources/application.conf
+++ b/eagle-core/eagle-app/eagle-app-base/src/test/resources/application.conf
@@ -51,4 +51,11 @@
 			"loader": "org.apache.eagle.app.service.impl.ApplicationProviderSPILoader"
 		}
 	}
+
+	"org.apache.eagle.app.storm.MockStormApplication": {
+		"spoutNum": 1234
+		"loaded": true
+		"mode":"LOCAL",
+		"appId":"test_topology_name"
+	}
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-app/eagle-app-base/src/test/resources/providers.xml
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/test/resources/providers.xml b/eagle-core/eagle-app/eagle-app-base/src/test/resources/providers.xml
index 3af7733..aba4c6c 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/test/resources/providers.xml
+++ b/eagle-core/eagle-app/eagle-app-base/src/test/resources/providers.xml
@@ -18,6 +18,6 @@
 <providers>
     <provider>
         <jarPath>target/apache-eagle-example-app.jar</jarPath>
-        <className>org.apache.eagle.app.TestApplicationImpl$Provider</className>
+        <className>org.apache.eagle.app.TestStormAppImpl$Provider</className>
     </provider>
 </providers>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/config/AbstractConfigOptionParser.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/config/AbstractConfigOptionParser.java b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/config/AbstractConfigOptionParser.java
new file mode 100644
index 0000000..a8a4b69
--- /dev/null
+++ b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/config/AbstractConfigOptionParser.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.eagle.common.config;
+
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.Parser;
+
+import java.util.Map;
+
+/**
+ * @since 8/22/15
+ */
+public abstract class AbstractConfigOptionParser {
+
+    // private final Options options;
+    private final Parser parser;
+
+    public AbstractConfigOptionParser(){
+        parser = parser();
+        //options = options();
+    }
+
+    /**
+     * @return Parser
+     */
+    protected abstract Parser parser();
+
+    /**
+     * @return Options
+     */
+    protected abstract Options options();
+
+    public abstract Map<String,String> parseConfig(String[] arguments) throws ParseException;
+
+    /**
+     * Load config as system properties
+     *
+     * @param arguments command line arguments
+     * @throws ParseException
+     */
+    public Config load(String[] arguments) throws ParseException {
+        Map<String,String> configProps = parseConfig(arguments);
+        for(Map.Entry<String,String> entry:configProps.entrySet()){
+            System.setProperty(entry.getKey(),entry.getValue());
+        }
+        System.setProperty("config.trace", "loads");
+        return ConfigFactory.load();
+    }
+
+    public CommandLine parse(String[] arguments) throws ParseException {
+        return this.parser.parse(this.options(),arguments);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/config/ConfigOptionParser.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/config/ConfigOptionParser.java b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/config/ConfigOptionParser.java
new file mode 100644
index 0000000..3cb42ca
--- /dev/null
+++ b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/config/ConfigOptionParser.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.eagle.common.config;
+
+import org.apache.commons.cli.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class ConfigOptionParser extends AbstractConfigOptionParser {
+    private final static String CONFIG_OPT_FLAG = "D";
+
+    @Override
+    protected Parser parser() {
+        return new BasicParser();
+    }
+
+    @Override
+    protected Options options() {
+        Options options = new Options();
+        options.addOption(CONFIG_OPT_FLAG, true, "Config properties in format of \"-D key=value\"");
+        return options;
+    }
+
+    @Override
+    public Map<String,String> parseConfig(String[] arguments) throws ParseException {
+        CommandLine cmd = parse(arguments);
+        return parseCommand(cmd);
+    }
+
+    protected Map<String,String> parseCommand(CommandLine cmd) throws ParseException {
+        Map<String,String> result = new HashMap<>();
+        if(cmd.hasOption(CONFIG_OPT_FLAG)){
+            String[] values = cmd.getOptionValues(CONFIG_OPT_FLAG);
+            for(String value:values){
+                int eqIndex = value.indexOf("=");
+                if(eqIndex>0 && eqIndex<value.length()){
+                    String k = value.substring(0,eqIndex);
+                    String v = value.substring(eqIndex+1,value.length());
+                    if(result.containsKey(k)){
+                        throw new ParseException("Duplicated "+CONFIG_OPT_FLAG+" "+value);
+                    }else{
+                        result.put(k,v);
+                    }
+                }else{
+                    throw new ParseException("Invalid format: -"+CONFIG_OPT_FLAG+" "+value+", required: -"+CONFIG_OPT_FLAG+" key=value");
+                }
+            }
+        }
+        return result;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-metadata/eagle-metadata-base/pom.xml
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/pom.xml b/eagle-core/eagle-metadata/eagle-metadata-base/pom.xml
index ffe8c73..48abd63 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-base/pom.xml
+++ b/eagle-core/eagle-metadata/eagle-metadata-base/pom.xml
@@ -23,6 +23,7 @@
         <artifactId>eagle-metadata</artifactId>
         <groupId>org.apache.eagle</groupId>
         <version>0.5.0-incubating-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/ApplicationDesc.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/ApplicationDesc.java b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/ApplicationDesc.java
index 46b5dbe..c4a609b 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/ApplicationDesc.java
+++ b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/ApplicationDesc.java
@@ -35,7 +35,7 @@ public class ApplicationDesc implements Serializable {
     private Class<?> providerClass;
     private Configuration configuration;
     private List<StreamDefinition> streams;
-    private Class<?> sinkClass;
+//    private Class<?> sinkClass;
     private ApplicationDocs docs;
 
     public String getDescription() {
@@ -115,13 +115,13 @@ public class ApplicationDesc implements Serializable {
         this.configuration = configuration;
     }
 
-    public Class<?> getSinkClass() {
-        return sinkClass;
-    }
-
-    public void setSinkClass(Class<?> sinkClass) {
-        this.sinkClass = sinkClass;
-    }
+//    public Class<?> getSinkType() {
+//        return sinkClass;
+//    }
+//
+//    public void setSinkClass(Class<?> sinkClass) {
+//        this.sinkClass = sinkClass;
+//    }
 
     public List<StreamDefinition> getStreams() {
         return streams;

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/ApplicationEntity.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/ApplicationEntity.java b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/ApplicationEntity.java
index 5302714..80b3669 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/ApplicationEntity.java
+++ b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/ApplicationEntity.java
@@ -21,6 +21,7 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties;
 
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -39,7 +40,7 @@ public class ApplicationEntity extends PersistenceEntity {
 
     private Map<String,Object> configuration = new HashMap<>();
     private Map<String,String> context = new HashMap<>();
-    private Collection<StreamDesc> streams;
+    private List<StreamDesc> streams;
     private Mode mode = Mode.CLUSTER;
     private Status status = Status.INITIALIZED;
 
@@ -110,11 +111,11 @@ public class ApplicationEntity extends PersistenceEntity {
         this.status = status;
     }
 
-    public Collection<StreamDesc> getStreams() {
+    public List<StreamDesc> getStreams() {
         return streams;
     }
 
-    public void setStreams(Collection<StreamDesc> streams) {
+    public void setStreams(List<StreamDesc> streams) {
         this.streams = streams;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamDesc.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamDesc.java b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamDesc.java
index 65b0dbf..abf6a81 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamDesc.java
+++ b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamDesc.java
@@ -21,7 +21,7 @@ import org.apache.eagle.alert.engine.coordinator.StreamDefinition;
 public class StreamDesc {
     private String streamId;
     private StreamDefinition schema;
-    private StreamSinkDesc sink;
+    private StreamSinkConfig sink;
 
     public String getStreamId() {
         return streamId;
@@ -39,11 +39,11 @@ public class StreamDesc {
         this.schema = streamSchema;
     }
 
-    public StreamSinkDesc getSink() {
+    public StreamSinkConfig getSink() {
         return sink;
     }
 
-    public void setSink(StreamSinkDesc sinkDesc) {
+    public void setSink(StreamSinkConfig sinkDesc) {
         this.sink = sinkDesc;
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamSinkConfig.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamSinkConfig.java b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamSinkConfig.java
new file mode 100644
index 0000000..a257265
--- /dev/null
+++ b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamSinkConfig.java
@@ -0,0 +1,25 @@
+/*
+ * 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.metadata.model;
+
+import java.io.Serializable;
+
+public interface StreamSinkConfig extends Serializable {
+    String getType();
+    Class<?> getSinkType();
+    Class<? extends StreamSinkConfig> getConfigType();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamSinkDesc.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamSinkDesc.java b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamSinkDesc.java
deleted file mode 100644
index 10b2b67..0000000
--- a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/model/StreamSinkDesc.java
+++ /dev/null
@@ -1,25 +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
- * <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.metadata.model;
-
-import java.io.Serializable;
-
-public interface StreamSinkDesc extends Serializable {
-    String getType();
-    Class<?> getSinkClass();
-    Class<? extends StreamSinkDesc> getDescClass();
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-core/eagle-metadata/eagle-metadata-jdbc/pom.xml
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-metadata/eagle-metadata-jdbc/pom.xml b/eagle-core/eagle-metadata/eagle-metadata-jdbc/pom.xml
index dd14854..4320520 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-jdbc/pom.xml
+++ b/eagle-core/eagle-metadata/eagle-metadata-jdbc/pom.xml
@@ -23,6 +23,7 @@
         <artifactId>eagle-metadata</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-metadata-jdbc</artifactId>

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-examples/eagle-app-example/pom.xml
----------------------------------------------------------------------
diff --git a/eagle-examples/eagle-app-example/pom.xml b/eagle-examples/eagle-app-example/pom.xml
index 5d00fc8..6b1b14d 100644
--- a/eagle-examples/eagle-app-example/pom.xml
+++ b/eagle-examples/eagle-app-example/pom.xml
@@ -42,5 +42,10 @@
                 <directory>src/main/resources</directory>
             </resource>
         </resources>
+        <testResources>
+            <testResource>
+                <directory>src/test/resources</directory>
+            </testResource>
+        </testResources>
     </build>
 </project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplication.java
----------------------------------------------------------------------
diff --git a/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplication.java b/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplication.java
deleted file mode 100644
index 5e6e548..0000000
--- a/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplication.java
+++ /dev/null
@@ -1,56 +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
- * <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.example;
-
-import backtype.storm.spout.SpoutOutputCollector;
-import backtype.storm.task.TopologyContext;
-import backtype.storm.topology.OutputFieldsDeclarer;
-import backtype.storm.topology.TopologyBuilder;
-import backtype.storm.topology.base.BaseRichSpout;
-import backtype.storm.tuple.Fields;
-import org.apache.eagle.app.AbstractApplication;
-import org.apache.eagle.app.ApplicationContext;
-
-import java.util.Arrays;
-import java.util.Map;
-
-public class ExampleApplication extends AbstractApplication {
-    protected void buildApp(TopologyBuilder builder, ApplicationContext context) {
-        builder.setSpout("metric_spout", new RandomEventSpout(), 4);
-        builder.setBolt("sink_1",context.getFlattenStreamSink("SAMPLE_STREAM_1")).fieldsGrouping("metric_spout",new Fields("metric"));
-        builder.setBolt("sink_2",context.getFlattenStreamSink("SAMPLE_STREAM_2")).fieldsGrouping("metric_spout",new Fields("metric"));
-    }
-
-    private class RandomEventSpout extends BaseRichSpout {
-        private SpoutOutputCollector _collector;
-        @Override
-        public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
-            _collector = spoutOutputCollector;
-        }
-
-        @Override
-        public void nextTuple() {
-            _collector.emit(Arrays.asList("disk.usage",System.currentTimeMillis(),"host_1",56.7));
-            _collector.emit(Arrays.asList("cpu.usage",System.currentTimeMillis(),"host_2",99.8));
-        }
-
-        @Override
-        public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
-            outputFieldsDeclarer.declare(new Fields("metric","timestamp","source","value"));
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplicationProvider.java
----------------------------------------------------------------------
diff --git a/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplicationProvider.java b/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplicationProvider.java
index 0efc7e1..7305817 100644
--- a/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplicationProvider.java
+++ b/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplicationProvider.java
@@ -21,13 +21,13 @@ import org.apache.eagle.app.spi.AbstractApplicationProvider;
 /**
  * Define application provider programmatically
  */
-public class ExampleApplicationProvider extends AbstractApplicationProvider<ExampleApplication> {
+public class ExampleApplicationProvider extends AbstractApplicationProvider<ExampleStormApplication> {
     public ExampleApplicationProvider() {
         super("/META-INF/apps/example/metadata.xml");
     }
 
     @Override
-    public ExampleApplication getApplication() {
-        return new ExampleApplication();
+    public ExampleStormApplication getApplication() {
+        return new ExampleStormApplication();
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplicationProvider2.java
----------------------------------------------------------------------
diff --git a/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplicationProvider2.java b/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplicationProvider2.java
index 0713aa0..d3d0f54 100644
--- a/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplicationProvider2.java
+++ b/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleApplicationProvider2.java
@@ -27,13 +27,13 @@ import java.util.List;
 /**
  * Define application provider with metadata.xml
  */
-public class ExampleApplicationProvider2 extends AbstractApplicationProvider<ExampleApplication> {
+public class ExampleApplicationProvider2 extends AbstractApplicationProvider<ExampleStormApplication> {
     @Override
     protected void configure() {
         setType("EXAMPLE_APPLICATION_2");
         setName("Example Monitoring Application 2");
         setVersion("0.5.0-incubating");
-        setAppClass(ExampleApplication.class);
+        setAppClass(ExampleStormApplication.class);
         setViewPath("/apps/example2");
         setAppConfig("ExampleApplicationConf.xml");
         setStreams(Arrays.asList(createSampleStreamDefinition("SAMPLE_STREAM_1"), createSampleStreamDefinition("SAMPLE_STREAM_2")));
@@ -56,7 +56,7 @@ public class ExampleApplicationProvider2 extends AbstractApplicationProvider<Exa
     }
 
     @Override
-    public ExampleApplication getApplication() {
-        return new ExampleApplication();
+    public ExampleStormApplication getApplication() {
+        return new ExampleStormApplication();
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleStormApplication.java
----------------------------------------------------------------------
diff --git a/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleStormApplication.java b/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleStormApplication.java
new file mode 100644
index 0000000..b29c6c5
--- /dev/null
+++ b/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleStormApplication.java
@@ -0,0 +1,60 @@
+/*
+ * 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.example;
+
+import backtype.storm.generated.StormTopology;
+import backtype.storm.spout.SpoutOutputCollector;
+import backtype.storm.task.TopologyContext;
+import backtype.storm.topology.OutputFieldsDeclarer;
+import backtype.storm.topology.TopologyBuilder;
+import backtype.storm.topology.base.BaseRichSpout;
+import backtype.storm.tuple.Fields;
+import org.apache.eagle.app.StormApplication;
+import org.apache.eagle.app.environment.impl.StormEnvironment;
+
+import java.util.Arrays;
+import java.util.Map;
+
+public class ExampleStormApplication extends StormApplication<ExampleStormConfig> {
+    @Override
+    public StormTopology execute(ExampleStormConfig config, StormEnvironment environment) {
+        TopologyBuilder builder = new TopologyBuilder();
+        builder.setSpout("metric_spout", new RandomEventSpout(), config.getSpoutNum());
+        builder.setBolt("sink_1",environment.getFlattenStreamSink("SAMPLE_STREAM_1",config)).fieldsGrouping("metric_spout",new Fields("metric"));
+        builder.setBolt("sink_2",environment.getFlattenStreamSink("SAMPLE_STREAM_2",config)).fieldsGrouping("metric_spout",new Fields("metric"));
+        return builder.createTopology();
+    }
+
+    private class RandomEventSpout extends BaseRichSpout {
+        private SpoutOutputCollector _collector;
+        @Override
+        public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
+            _collector = spoutOutputCollector;
+        }
+
+        @Override
+        public void nextTuple() {
+            _collector.emit(Arrays.asList("disk.usage",System.currentTimeMillis(),"host_1",56.7));
+            _collector.emit(Arrays.asList("cpu.usage",System.currentTimeMillis(),"host_2",99.8));
+        }
+
+        @Override
+        public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
+            outputFieldsDeclarer.declare(new Fields("metric","timestamp","source","value"));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleStormConfig.java
----------------------------------------------------------------------
diff --git a/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleStormConfig.java b/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleStormConfig.java
new file mode 100644
index 0000000..7c35bcf
--- /dev/null
+++ b/eagle-examples/eagle-app-example/src/main/java/org/apache/eagle/app/example/ExampleStormConfig.java
@@ -0,0 +1,20 @@
+package org.apache.eagle.app.example;
+
+import org.apache.eagle.app.Configuration;
+
+public class ExampleStormConfig extends Configuration {
+    private int spoutNum = 1;
+
+    public ExampleStormConfig(){}
+    public ExampleStormConfig(String appName){
+        this.setAppId(appName);
+    }
+
+    public int getSpoutNum() {
+        return spoutNum;
+    }
+
+    public void setSpoutNum(int spoutNum) {
+        this.spoutNum = spoutNum;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-examples/eagle-app-example/src/main/resources/META-INF/apps/example/metadata.xml
----------------------------------------------------------------------
diff --git a/eagle-examples/eagle-app-example/src/main/resources/META-INF/apps/example/metadata.xml b/eagle-examples/eagle-app-example/src/main/resources/META-INF/apps/example/metadata.xml
index b6a8569..66e734f 100644
--- a/eagle-examples/eagle-app-example/src/main/resources/META-INF/apps/example/metadata.xml
+++ b/eagle-examples/eagle-app-example/src/main/resources/META-INF/apps/example/metadata.xml
@@ -20,7 +20,7 @@
     <type>EXAMPLE_APPLICATION</type>
     <name>Example Monitoring Application</name>
     <version>0.5.0-incubating</version>
-    <appClass>org.apache.eagle.app.example.ExampleApplication</appClass>
+    <appClass>org.apache.eagle.app.example.ExampleStormApplication</appClass>
     <viewPath>/apps/example</viewPath>
     <configuration>
         <property>

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-examples/eagle-app-example/src/test/java/org/apache/eagle/app/example/ExampleApplicationProviderTest.java
----------------------------------------------------------------------
diff --git a/eagle-examples/eagle-app-example/src/test/java/org/apache/eagle/app/example/ExampleApplicationProviderTest.java b/eagle-examples/eagle-app-example/src/test/java/org/apache/eagle/app/example/ExampleApplicationProviderTest.java
new file mode 100644
index 0000000..45dd7bd
--- /dev/null
+++ b/eagle-examples/eagle-app-example/src/test/java/org/apache/eagle/app/example/ExampleApplicationProviderTest.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.example;
+
+import com.google.inject.Inject;
+import org.apache.eagle.app.resource.ApplicationResource;
+import org.apache.eagle.app.service.ApplicationOperations;
+import org.apache.eagle.app.test.ServerSimulator;
+import org.apache.eagle.app.test.AppUnitTestRunner;
+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.resource.SiteResource;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collection;
+
+@RunWith(AppUnitTestRunner.class)
+public class ExampleApplicationProviderTest {
+    @Inject private SiteResource siteResource;
+    @Inject private ApplicationResource applicationResource;
+    @Inject private ServerSimulator simulator;
+
+    @Test
+    public void testApplicationProviderLoading(){
+        Collection<ApplicationDesc> applicationDescs = applicationResource.getApplicationDescs().getData();
+        Assert.assertNotNull(applicationDescs);
+        Assert.assertEquals(2,applicationDescs.size());
+    }
+
+    /**
+     * register site
+     * install app
+     * start app
+     * stop app
+     * uninstall app
+     *
+     * @throws InterruptedException
+     */
+    @Test
+    public void testApplicationLifecycle() throws InterruptedException {
+        // Create local site
+        SiteEntity siteEntity = new SiteEntity();
+        siteEntity.setSiteId("test_site");
+        siteEntity.setSiteName("Test Site");
+        siteEntity.setDescription("Test Site for ExampleApplicationProviderTest");
+        siteResource.createSite(siteEntity);
+        Assert.assertNotNull(siteEntity.getUuid());
+
+        // Install application
+        ApplicationEntity applicationEntity = applicationResource.installApplication(new ApplicationOperations.InstallOperation("test_site","EXAMPLE_APPLICATION", ApplicationEntity.Mode.LOCAL)).getData();
+        // Start application
+        applicationResource.startApplication(new ApplicationOperations.StartOperation(applicationEntity.getUuid()));
+        // Stop application
+        applicationResource.stopApplication(new ApplicationOperations.StopOperation(applicationEntity.getUuid()));
+        // Uninstall application
+        applicationResource.uninstallApplication(new ApplicationOperations.UninstallOperation(applicationEntity.getUuid()));
+        try {
+            applicationResource.getApplicationEntityByUUID(applicationEntity.getUuid());
+            Assert.fail("Application instance (UUID: "+applicationEntity.getUuid()+") should have been uninstalled");
+        } catch (Exception ex){
+            // Expected exception
+        }
+    }
+
+    @Test
+    public void testApplicationQuickRunWithAppType(){
+        simulator.start("EXAMPLE_APPLICATION");
+    }
+
+    @Test
+    public void testApplicationQuickRunWithAppProvider(){
+        simulator.start(ExampleApplicationProvider.class);
+    }
+
+    @Test
+    public void testApplicationQuickRunWithAppProvider2(){
+        simulator.start(ExampleApplicationProvider2.class);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-examples/eagle-app-example/src/test/java/org/apache/eagle/app/example/ExampleApplicationTest.java
----------------------------------------------------------------------
diff --git a/eagle-examples/eagle-app-example/src/test/java/org/apache/eagle/app/example/ExampleApplicationTest.java b/eagle-examples/eagle-app-example/src/test/java/org/apache/eagle/app/example/ExampleApplicationTest.java
index 4383907..7040e19 100644
--- a/eagle-examples/eagle-app-example/src/test/java/org/apache/eagle/app/example/ExampleApplicationTest.java
+++ b/eagle-examples/eagle-app-example/src/test/java/org/apache/eagle/app/example/ExampleApplicationTest.java
@@ -1,104 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.eagle.app.example;
-
-import com.google.inject.Inject;
-import org.apache.eagle.app.resource.ApplicationResource;
-import org.apache.eagle.app.service.ApplicationOperations;
-import org.apache.eagle.app.test.ApplicationSimulator;
-import org.apache.eagle.app.test.AppUnitTestRunner;
-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.resource.SiteResource;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Collection;
-
-@RunWith(AppUnitTestRunner.class)
-public class ExampleApplicationTest {
-    @Inject private SiteResource siteResource;
-    @Inject private ApplicationResource applicationResource;
-    @Inject private ApplicationSimulator simulator;
-
-    @Test
-    public void testApplicationProviderLoading(){
-        Collection<ApplicationDesc> applicationDescs = applicationResource.getApplicationDescs().getData();
-        Assert.assertNotNull(applicationDescs);
-        Assert.assertEquals(2,applicationDescs.size());
-    }
-
-    /**
-     * register site
-     * install app
-     * start app
-     * stop app
-     * uninstall app
-     *
-     * @throws InterruptedException
-     */
-    @Test
-    public void testApplicationLifecycle() throws InterruptedException {
-        // Create local site
-        SiteEntity siteEntity = new SiteEntity();
-        siteEntity.setSiteId("test_site");
-        siteEntity.setSiteName("Test Site");
-        siteEntity.setDescription("Test Site for ExampleApplicationTest");
-        siteResource.createSite(siteEntity);
-        Assert.assertNotNull(siteEntity.getUuid());
-
-        // Install application
-        ApplicationEntity applicationEntity = applicationResource.installApplication(new ApplicationOperations.InstallOperation("test_site","EXAMPLE_APPLICATION", ApplicationEntity.Mode.LOCAL)).getData();
-        // Start application
-        applicationResource.startApplication(new ApplicationOperations.StartOperation(applicationEntity.getUuid()));
-        // Stop application
-        applicationResource.stopApplication(new ApplicationOperations.StopOperation(applicationEntity.getUuid()));
-        // Uninstall application
-        applicationResource.uninstallApplication(new ApplicationOperations.UninstallOperation(applicationEntity.getUuid()));
-        try {
-            applicationResource.getApplicationEntityByUUID(applicationEntity.getUuid());
-            Assert.fail("Application instance (UUID: "+applicationEntity.getUuid()+") should have been uninstalled");
-        } catch (Exception ex){
-            // Expected exception
-        }
-    }
-
-    @Test
-    public void testApplicationQuickRunWithAppType(){
-        simulator.submit("EXAMPLE_APPLICATION");
-    }
-
-    @Test
-    public void testApplicationQuickRunWithAppProvider(){
-        simulator.submit(ExampleApplicationProvider.class);
-    }
-
-    @Test
-    public void testApplicationQuickRunWithAppProvider2(){
-        simulator.submit(ExampleApplicationProvider2.class);
-    }
-
-    /**
-     * For DEBUG
-     * @param args
-     */
-    public static void main(String[] args){
-        ApplicationSimulator.getInstance().submit(ExampleApplicationProvider.class);
-    }
-}
\ No newline at end of file
+/*
+ * 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.example;
+
+import org.junit.Test;
+
+public class ExampleApplicationTest {
+    @Test
+    public void testRunWithAppTool(){
+        new ExampleStormApplication().run(new ExampleStormConfig("unittest_app_topology"));
+    }
+
+    /**
+     * Should load application from application.conf:
+     * {
+     *     org.apache.eagle.app.example.ExampleStormApplication{
+     *          appId: VALUE,
+     *          mode: LOCAL,
+     *          {Attribute}:{Value}
+     *     }
+     * }
+     */
+    @Test
+    public void testRunWithAppToolFromEnvConfig(){
+        new ExampleStormApplication().run();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-examples/eagle-app-example/src/test/java/resources/application.conf
----------------------------------------------------------------------
diff --git a/eagle-examples/eagle-app-example/src/test/java/resources/application.conf b/eagle-examples/eagle-app-example/src/test/java/resources/application.conf
deleted file mode 100644
index 18677b2..0000000
--- a/eagle-examples/eagle-app-example/src/test/java/resources/application.conf
+++ /dev/null
@@ -1,58 +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.
-
-{
-	"coordinator" : {
-		"policiesPerBolt" : 5,
-		"boltParallelism" : 5,
-		"policyDefaultParallelism" : 5,
-		"boltLoadUpbound": 0.8,
-		"topologyLoadUpbound" : 0.8,
-		"numOfAlertBoltsPerTopology" : 5,
-		"zkConfig" : {
-			"zkQuorum" : "127.0.0.1:2181",
-			"zkRoot" : "/alert",
-			"zkSessionTimeoutMs" : 10000,
-			"connectionTimeoutMs" : 10000,
-			"zkRetryTimes" : 3,
-			"zkRetryInterval" : 3000
-		},
-		"metadataService" : {
-			"host" : "localhost",
-			"port" : 8080,
-			"context" : "/rest"
-		},
-		"metadataDynamicCheck" : {
-			"initDelayMillis" : 1000,
-			"delayMillis" : 30000
-		}
-	},
-	"metadata":{
-		"store": "org.apache.eagle.metadata.service.memory.MemoryMetadataStore"
-	},
-	"application":{
-		"sink":{
-			"type": "org.apache.eagle.app.sink.KafkaStreamSink",
-			"config": {
-				"kafkaBrokerHost" : "",
-				"kafkaZkConnection" : ""
-			}
-		},
-		"storm": {
-			"nimbusHost": "localhost"
-			"nimbusThriftPort": 6627
-		}
-	}
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-examples/eagle-app-example/src/test/resources/application.conf
----------------------------------------------------------------------
diff --git a/eagle-examples/eagle-app-example/src/test/resources/application.conf b/eagle-examples/eagle-app-example/src/test/resources/application.conf
new file mode 100644
index 0000000..bfbf20e
--- /dev/null
+++ b/eagle-examples/eagle-app-example/src/test/resources/application.conf
@@ -0,0 +1,62 @@
+# 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.
+
+{
+	"coordinator" : {
+		"policiesPerBolt" : 5,
+		"boltParallelism" : 5,
+		"policyDefaultParallelism" : 5,
+		"boltLoadUpbound": 0.8,
+		"topologyLoadUpbound" : 0.8,
+		"numOfAlertBoltsPerTopology" : 5,
+		"zkConfig" : {
+			"zkQuorum" : "127.0.0.1:2181",
+			"zkRoot" : "/alert",
+			"zkSessionTimeoutMs" : 10000,
+			"connectionTimeoutMs" : 10000,
+			"zkRetryTimes" : 3,
+			"zkRetryInterval" : 3000
+		},
+		"metadataService" : {
+			"host" : "localhost",
+			"port" : 8080,
+			"context" : "/rest"
+		},
+		"metadataDynamicCheck" : {
+			"initDelayMillis" : 1000,
+			"delayMillis" : 30000
+		}
+	},
+	"metadata":{
+		"store": "org.apache.eagle.metadata.service.memory.MemoryMetadataStore"
+	},
+	"application":{
+		"sink":{
+			"type": "org.apache.eagle.app.sink.KafkaStreamSink",
+			"config": {
+				"kafkaBrokerHost" : "",
+				"kafkaZkConnection" : ""
+			}
+		},
+		"storm": {
+			"nimbusHost": "localhost"
+			"nimbusThriftPort": 6627
+		}
+	},
+
+	"org.apache.eagle.app.example.ExampleStormApplication": {
+		"appId": "unit_test_example_app"
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-external/eagle-ambari/lib/EAGLE/package/patches/app.js
----------------------------------------------------------------------
diff --git a/eagle-external/eagle-ambari/lib/EAGLE/package/patches/app.js b/eagle-external/eagle-ambari/lib/EAGLE/package/patches/app.js
index bfc0678..335722a 100644
--- a/eagle-external/eagle-ambari/lib/EAGLE/package/patches/app.js
+++ b/eagle-external/eagle-ambari/lib/EAGLE/package/patches/app.js
@@ -167656,9 +167656,7 @@ var App = require('app');
  *
  * @extends App.ChartLinearTimeView
  * @extends Ember.Object
- * @extends Ember.View
- */
-App.ChartServiceMetricsYARN_ApplicationCurrentStates = App.ChartLinearTimeView.extend({
+ * @extends Ember.ViApp.ChartServiceMetricsYARN_ApplicationCurrentStates = App.ChartLinearTimeView.extend({
   id: "service-metrics-yarn-apps-current-states",
   title: Em.I18n.t('services.service.info.metrics.yarn.apps.states.current.title'),
   renderer: 'line',

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-jpm/eagle-jpm-app/pom.xml
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-app/pom.xml b/eagle-jpm/eagle-jpm-app/pom.xml
index 1b545d1..fd65188 100644
--- a/eagle-jpm/eagle-jpm-app/pom.xml
+++ b/eagle-jpm/eagle-jpm-app/pom.xml
@@ -31,6 +31,11 @@
             <artifactId>eagle-app-base</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.hadoop</groupId>
+            <artifactId>hadoop-yarn-server-common</artifactId>
+            <version>2.7.0</version>
+        </dependency>
     </dependencies>
     <build>
         <resources>

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-jpm/eagle-jpm-app/src/main/java/org/apache/eagle/app/jpm/JPMApplication.java
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-app/src/main/java/org/apache/eagle/app/jpm/JPMApplication.java b/eagle-jpm/eagle-jpm-app/src/main/java/org/apache/eagle/app/jpm/JPMApplication.java
index 7fecbf4..89e5433 100644
--- a/eagle-jpm/eagle-jpm-app/src/main/java/org/apache/eagle/app/jpm/JPMApplication.java
+++ b/eagle-jpm/eagle-jpm-app/src/main/java/org/apache/eagle/app/jpm/JPMApplication.java
@@ -16,23 +16,27 @@
  */
 package org.apache.eagle.app.jpm;
 
+import backtype.storm.generated.StormTopology;
 import backtype.storm.spout.SpoutOutputCollector;
 import backtype.storm.task.TopologyContext;
 import backtype.storm.topology.OutputFieldsDeclarer;
 import backtype.storm.topology.TopologyBuilder;
 import backtype.storm.topology.base.BaseRichSpout;
 import backtype.storm.tuple.Fields;
-import org.apache.eagle.app.AbstractApplication;
-import org.apache.eagle.app.ApplicationContext;
+import org.apache.eagle.app.StormApplication;
+import org.apache.eagle.app.environment.impl.StormEnvironment;
 
 import java.util.Arrays;
 import java.util.Map;
 
-public class JPMApplication extends AbstractApplication {
-    protected void buildApp(TopologyBuilder builder, ApplicationContext context) {
+public class JPMApplication extends StormApplication<JPMConfiguration> {
+    @Override
+    public StormTopology execute(JPMConfiguration config, StormEnvironment environment) {
+        TopologyBuilder builder = new TopologyBuilder();
         builder.setSpout("metric_spout", new RandomEventSpout(), 4);
-        builder.setBolt("sink_1",context.getFlattenStreamSink("SAMPLE_STREAM_1")).fieldsGrouping("metric_spout",new Fields("metric"));
-        builder.setBolt("sink_2",context.getFlattenStreamSink("SAMPLE_STREAM_2")).fieldsGrouping("metric_spout",new Fields("metric"));
+        builder.setBolt("sink_1",environment.getFlattenStreamSink("SAMPLE_STREAM_1",config)).fieldsGrouping("metric_spout",new Fields("metric"));
+        builder.setBolt("sink_2",environment.getFlattenStreamSink("SAMPLE_STREAM_2",config)).fieldsGrouping("metric_spout",new Fields("metric"));
+        return builder.createTopology();
     }
 
     private class RandomEventSpout extends BaseRichSpout {

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-jpm/eagle-jpm-app/src/main/java/org/apache/eagle/app/jpm/JPMConfiguration.java
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-app/src/main/java/org/apache/eagle/app/jpm/JPMConfiguration.java b/eagle-jpm/eagle-jpm-app/src/main/java/org/apache/eagle/app/jpm/JPMConfiguration.java
new file mode 100644
index 0000000..7b284c6
--- /dev/null
+++ b/eagle-jpm/eagle-jpm-app/src/main/java/org/apache/eagle/app/jpm/JPMConfiguration.java
@@ -0,0 +1,23 @@
+/*
+ * 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.jpm;
+
+import org.apache.eagle.app.Configuration;
+
+public class JPMConfiguration extends Configuration {
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-jpm/eagle-jpm-app/src/main/resources/META-INF/apps/jpm/metadata.xml
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-app/src/main/resources/META-INF/apps/jpm/metadata.xml b/eagle-jpm/eagle-jpm-app/src/main/resources/META-INF/apps/jpm/metadata.xml
index c2c77e2..a513efa 100644
--- a/eagle-jpm/eagle-jpm-app/src/main/resources/META-INF/apps/jpm/metadata.xml
+++ b/eagle-jpm/eagle-jpm-app/src/main/resources/META-INF/apps/jpm/metadata.xml
@@ -17,7 +17,7 @@
   -->
 
 <application>
-    <type>JPM</type>
+    <type>JPM_APP</type>
     <name>Job Performance Monitoring Application</name>
     <version>0.5.0-incubating</version>
     <appClass>org.apache.eagle.app.jpm.JPMApplication</appClass>

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-jpm/eagle-jpm-app/src/test/java/org/apache/eagle/app/jpm/JPMApplicationTest.java
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-app/src/test/java/org/apache/eagle/app/jpm/JPMApplicationTest.java b/eagle-jpm/eagle-jpm-app/src/test/java/org/apache/eagle/app/jpm/JPMApplicationTest.java
index a78bbae..645a193 100644
--- a/eagle-jpm/eagle-jpm-app/src/test/java/org/apache/eagle/app/jpm/JPMApplicationTest.java
+++ b/eagle-jpm/eagle-jpm-app/src/test/java/org/apache/eagle/app/jpm/JPMApplicationTest.java
@@ -20,7 +20,6 @@ import com.google.inject.Inject;
 import org.apache.eagle.app.resource.ApplicationResource;
 import org.apache.eagle.app.service.ApplicationOperations;
 import org.apache.eagle.app.test.AppUnitTestRunner;
-import org.apache.eagle.app.test.ApplicationSimulator;
 import org.apache.eagle.metadata.model.ApplicationEntity;
 import org.apache.eagle.metadata.model.SiteEntity;
 import org.apache.eagle.metadata.resource.SiteResource;

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/4ad1a418/eagle-server/src/main/java/org/apache/eagle/server/ServerMain.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/ServerMain.java b/eagle-server/src/main/java/org/apache/eagle/server/ServerMain.java
index 50bd878..968a93c 100644
--- a/eagle-server/src/main/java/org/apache/eagle/server/ServerMain.java
+++ b/eagle-server/src/main/java/org/apache/eagle/server/ServerMain.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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.
@@ -17,7 +17,20 @@
 package org.apache.eagle.server;
 
 public class ServerMain {
-    public static void main(String[] args) throws Exception {
-        new ServerApplication().run(args);
+    public static void main(String[] args) {
+        System.out.println(
+            "Welcome to Apache Eagle (Incubating)\n"+
+            "---------------"
+        );
+        System.out.println(
+            "Starting Eagle Server ..."
+        );
+        try {
+            new ServerApplication().run(args);
+        } catch (Exception e) {
+            System.err.println("Got exception: "+e.getMessage());
+            e.printStackTrace();
+            System.exit(1);
+        }
     }
-}
+}
\ No newline at end of file


Mime
View raw message