You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@eagle.apache.org by ha...@apache.org on 2016/09/13 12:18:48 UTC
[2/2] incubator-eagle git commit: [EAGLE-536] Support application
dependency
[EAGLE-536] Support application dependency
# Changes
* Support to declare dependency descriptor and validation
* Support to export executable flag in REST API for front-end to aware whether an application can be START/STOP/STATUS or not.
* Add dependency checking logic while installing application , if required dependency is not installed, throw exception back, so that front-end can simply treat an ApplicationPackage consist of a set of Applications as a normal application.
# Use Case
JPM Application has some back-end application like MR history/running, Spark history/running, while has single Web App, so user could simply understand the application JPM as following, where right-side is tech view and left-side is product view:
~~~
JPM = JPM WEB {
dependencies = [MR history/running, Spark history/running]
}
~~~
Author: Hao Chen <ha...@apache.org>
Closes #435 from haoch/EAGLE-536.
Project: http://git-wip-us.apache.org/repos/asf/incubator-eagle/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-eagle/commit/83bd4e3d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-eagle/tree/83bd4e3d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-eagle/diff/83bd4e3d
Branch: refs/heads/master
Commit: 83bd4e3d7c538052bb1f3048dfad4ad1f05a7738
Parents: 2c30276
Author: Hao Chen <ha...@apache.org>
Authored: Tue Sep 13 20:18:26 2016 +0800
Committer: Hao Chen <ha...@apache.org>
Committed: Tue Sep 13 20:18:26 2016 +0800
----------------------------------------------------------------------
.../engine/coordinator/StreamDefinition.java | 4 +-
.../apache/eagle/app/AbstractApplication.java | 28 ----
.../java/org/apache/eagle/app/Application.java | 2 +
.../apache/eagle/app/ExecutableApplication.java | 33 ++++
.../apache/eagle/app/StaticWebApplication.java | 60 ++++++++
.../eagle/app/StaticWebApplicationProvider.java | 34 +++++
.../org/apache/eagle/app/StormApplication.java | 2 +-
.../app/config/ApplicationProviderConfig.java | 2 +-
.../config/ApplicationProviderDescConfig.java | 50 +++---
.../app/environment/AbstractEnvironment.java | 2 +-
.../eagle/app/environment/Environment.java | 6 +
.../environment/ExecutionRuntimeManager.java | 6 +-
.../app/environment/impl/WebEnvironment.java | 39 +++++
.../environment/impl/WebExecutionContainer.java | 34 +++++
.../environment/impl/WebExecutionRuntime.java | 66 ++++++++
.../java/org/apache/eagle/app/package-info.java | 2 +-
.../eagle/app/service/ApplicationContext.java | 149 ------------------
.../service/ApplicationOperationContext.java | 153 +++++++++++++++++++
.../app/service/ApplicationProviderLoader.java | 2 +-
.../impl/ApplicationManagementServiceImpl.java | 74 +++++----
.../impl/ApplicationProviderConfigLoader.java | 4 +
.../impl/ApplicationProviderSPILoader.java | 3 +
.../impl/ApplicationProviderServiceImpl.java | 53 ++++++-
.../app/spi/AbstractApplicationProvider.java | 54 +------
.../eagle/app/spi/ApplicationDescLoader.java | 27 ++++
.../eagle/app/spi/ApplicationProvider.java | 37 ++++-
.../app/spi/ApplicationXMLDescriptorLoader.java | 69 +++++++++
.../app/ApplicationProviderDescConfigTest.java | 30 ++--
.../app/ApplicationProviderServiceTest.java | 28 ++--
.../apache/eagle/app/TestStormApplication.java | 2 +-
.../apache/eagle/app/TestWebApplication.java | 27 ++++
.../app/service/ApplicationContextTest.java | 48 ------
.../ApplicationOperationContextTest.java | 48 ++++++
....eagle.app.TestStormApplication$Provider.xml | 1 -
...he.eagle.app.TestWebApplication$Provider.xml | 30 ++++
...org.apache.eagle.app.spi.ApplicationProvider | 3 +-
.../eagle-embed/eagle-embed-hbase/pom.xml | 4 -
.../metadata/model/ApplicationDependency.java | 56 +++++++
.../eagle/metadata/model/ApplicationDesc.java | 14 +-
.../eagle/metadata/model/ApplicationEntity.java | 19 ++-
.../ApplicationEntityServiceMemoryImpl.java | 42 ++---
.../example/ExampleApplicationProviderTest.java | 36 +++--
eagle-jpm/eagle-jpm-app/pom.xml | 46 ------
.../apache/eagle/app/jpm/JPMApplication.java | 64 --------
.../eagle/app/jpm/JPMApplicationProvider.java | 29 ----
...che.eagle.app.jpm.JPMApplicationProvider.xml | 109 -------------
...org.apache.eagle.app.spi.ApplicationProvider | 16 --
.../src/main/webapp/app/apps/jpm/index.html | 6 -
.../eagle-jpm-app/src/main/webapp/package.json | 0
.../eagle/app/jpm/JPMApplicationTest.java | 86 -----------
....history.MRHistoryJobApplicationProvider.xml | 4 +-
eagle-jpm/eagle-jpm-web/pom.xml | 59 +++++++
.../app/jpm/JPMWebApplicationProvider.java | 23 +++
....eagle.app.jpm.JPMWebApplicationProvider.xml | 43 ++++++
...org.apache.eagle.app.spi.ApplicationProvider | 16 ++
.../src/main/webapp/app/apps/jpm/index.html | 6 +
.../eagle-jpm-web/src/main/webapp/package.json | 0
.../eagle/app/jpm/JPMWebApplicationTest.java | 102 +++++++++++++
eagle-jpm/pom.xml | 2 +-
...ecurity.auditlog.HdfsAuditLogAppProvider.xml | 1 -
eagle-server/pom.xml | 91 +++++++----
...org.apache.eagle.app.spi.ApplicationProvider | 2 +-
62 files changed, 1276 insertions(+), 812 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/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 9130951..a23c963 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,11 +16,11 @@
*/
package org.apache.eagle.alert.engine.coordinator;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
/**
* This is actually a data source schema.
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/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
deleted file mode 100644
index 8943df3..0000000
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/AbstractApplication.java
+++ /dev/null
@@ -1,28 +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;
-
-import org.apache.eagle.app.environment.Environment;
-import org.apache.eagle.app.environment.ExecutionRuntimeManager;
-import com.typesafe.config.Config;
-
-public abstract class AbstractApplication<E extends Environment, P> implements Application<E, P>, ApplicationTool {
- @Override
- public void run(Config config) {
- ExecutionRuntimeManager.getInstance().getRuntime(getEnvironmentType(), config).start(this, config);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/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
index 84398b1..d76e468 100644
--- 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
@@ -52,4 +52,6 @@ public interface Application<
* @return application environment type
*/
Class<? extends E> getEnvironmentType();
+
+ boolean isExecutable();
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ExecutableApplication.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ExecutableApplication.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ExecutableApplication.java
new file mode 100644
index 0000000..6463d47
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/ExecutableApplication.java
@@ -0,0 +1,33 @@
+/*
+ * 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 org.apache.eagle.app.environment.Environment;
+import org.apache.eagle.app.environment.ExecutionRuntimeManager;
+import com.typesafe.config.Config;
+
+public abstract class ExecutableApplication<E extends Environment, P> implements Application<E, P>, ApplicationTool {
+ @Override
+ public void run(Config config) {
+ ExecutionRuntimeManager.getInstance().getRuntime(getEnvironmentType(), config).start(this, config);
+ }
+
+ @Override
+ public boolean isExecutable() {
+ return true;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StaticWebApplication.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StaticWebApplication.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StaticWebApplication.java
new file mode 100644
index 0000000..fae9393
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StaticWebApplication.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;
+
+import com.typesafe.config.Config;
+import org.apache.eagle.app.environment.impl.WebExecutionContainer;
+import org.apache.eagle.app.environment.impl.WebEnvironment;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Static Web Application without executable process.
+ */
+public class StaticWebApplication implements Application<WebEnvironment, WebExecutionContainer> {
+ private static final Logger LOGGER = LoggerFactory.getLogger(StaticWebApplication.class);
+ private final String webViewPath;
+
+ public StaticWebApplication(String webViewPath) {
+ this.webViewPath = webViewPath;
+ }
+
+ @Override
+ public WebExecutionContainer execute(Config config, WebEnvironment environment) {
+ LOGGER.warn("Executing web application");
+ return new WebExecutionContainer(this);
+ }
+
+ @Override
+ public Class<? extends WebEnvironment> getEnvironmentType() {
+ return WebEnvironment.class;
+ }
+
+ @Override
+ public boolean isExecutable() {
+ return false;
+ }
+
+ public String getWebViewPath() {
+ return webViewPath;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("StaticWebApplication(%s)",this.getWebViewPath());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StaticWebApplicationProvider.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StaticWebApplicationProvider.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StaticWebApplicationProvider.java
new file mode 100644
index 0000000..12d8f4e
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StaticWebApplicationProvider.java
@@ -0,0 +1,34 @@
+/*
+ * 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 org.apache.eagle.app.spi.AbstractApplicationProvider;
+
+/**
+ * Static Web Application Provider.
+ */
+public abstract class StaticWebApplicationProvider extends AbstractApplicationProvider<StaticWebApplication> {
+ @Override
+ public StaticWebApplication getApplication() {
+ return new StaticWebApplication(this.getApplicationDesc().getViewPath());
+ }
+
+ @Override
+ public final Class<StaticWebApplication> getApplicationClass() {
+ return StaticWebApplication.class;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StormApplication.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StormApplication.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StormApplication.java
index 7e70cde..05fc512 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StormApplication.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/StormApplication.java
@@ -19,7 +19,7 @@ package org.apache.eagle.app;
import org.apache.eagle.app.environment.impl.StormEnvironment;
import backtype.storm.generated.StormTopology;
-public abstract class StormApplication extends AbstractApplication<StormEnvironment, StormTopology> {
+public abstract class StormApplication extends ExecutableApplication<StormEnvironment, StormTopology> {
@Override
public Class<? extends StormEnvironment> getEnvironmentType() {
return StormEnvironment.class;
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/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
index b787885..16438a0 100644
--- 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
@@ -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.
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/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
index 7f0dbb0..2d2b7e2 100644
--- 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
@@ -16,27 +16,38 @@
*/
package org.apache.eagle.app.config;
-
import org.apache.eagle.alert.engine.coordinator.StreamDefinition;
+import org.apache.eagle.metadata.model.ApplicationDependency;
import org.apache.eagle.metadata.model.ApplicationDocs;
import org.apache.eagle.metadata.model.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.InputStream;
-import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.*;
+import java.io.InputStream;
+import java.util.List;
+/**
+ * Application Metadata Descriptor Unmarshalling POJO.
+ *
+ * @see org.apache.eagle.app.spi.ApplicationProvider
+ */
@XmlRootElement(name = "application")
@XmlAccessorType(XmlAccessType.FIELD)
public class ApplicationProviderDescConfig {
+
+ @XmlElement(required = true)
private String type;
+
+ @XmlElement(required = true)
private String name;
+
+ @XmlElement(required = true)
private String version;
+
private String description;
- private String appClass;
private String viewPath;
private Configuration configuration;
private ApplicationDocs docs;
@@ -45,6 +56,10 @@ public class ApplicationProviderDescConfig {
@XmlElement(name = "stream")
private List<StreamDefinition> streams;
+ @XmlElementWrapper(name = "dependencies")
+ @XmlElement(name = "dependency")
+ private List<ApplicationDependency> dependencies;
+
public String getDescription() {
return description;
}
@@ -91,8 +106,9 @@ public class ApplicationProviderDescConfig {
@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());
+ return String.format("ApplicationDesc [type=%s, name=%s, version=%s, viewPath=%s, configuration= %s properties, description=%s",
+ getType(), getName(), getVersion(), getViewPath(),
+ getConfiguration() == null ? 0 : getConfiguration().size(), getDescription());
}
public void setConfiguration(Configuration configuration) {
@@ -121,23 +137,15 @@ public class ApplicationProviderDescConfig {
}
if (is == null) {
LOG.error("Application descriptor configuration {} is not found", configXmlFile);
- throw new IllegalStateException("Application descriptor configuration " + configXmlFile + " is not found");
+ throw new IllegalStateException("Application descriptor " + 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);
+ LOG.error("Failed to load application descriptor: {}", configXmlFile, ex);
+ throw new IllegalStateException("Failed to load application descriptor: " + configXmlFile, ex);
}
}
- public String getAppClass() {
- return appClass;
- }
-
- public void setAppClass(String appClass) {
- this.appClass = appClass;
- }
-
public ApplicationDocs getDocs() {
return docs;
}
@@ -145,4 +153,12 @@ public class ApplicationProviderDescConfig {
public void setDocs(ApplicationDocs docs) {
this.docs = docs;
}
+
+ public List<ApplicationDependency> getDependencies() {
+ return dependencies;
+ }
+
+ public void setDependencies(List<ApplicationDependency> dependencies) {
+ this.dependencies = dependencies;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/AbstractEnvironment.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/AbstractEnvironment.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/AbstractEnvironment.java
index 45de7b9..02c130a 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/AbstractEnvironment.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/AbstractEnvironment.java
@@ -24,6 +24,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractEnvironment implements Environment {
+
private final Config config;
private final StreamSinkProvider sinkProvider;
private static final String APPLICATIONS_SINK_TYPE_PROPS_KEY = "application.sink.provider";
@@ -59,7 +60,6 @@ public abstract class AbstractEnvironment implements Environment {
.append(this.config()).build();
}
- @Override
public StreamSinkProvider streamSink() {
return sinkProvider;
}
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/Environment.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/Environment.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/Environment.java
index 9569c5f..29e90d9 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/Environment.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/Environment.java
@@ -25,7 +25,13 @@ import java.io.Serializable;
* Execution Environment Context.
*/
public interface Environment extends Serializable {
+
Config config();
+ /**
+ * TODO Only useful for Storm/Spark Exeuctable Application instead of static web application.
+ *
+ * @return StreamSinkProvider.
+ */
StreamSinkProvider streamSink();
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/ExecutionRuntimeManager.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/ExecutionRuntimeManager.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/ExecutionRuntimeManager.java
index fc1e632..96f171e 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/ExecutionRuntimeManager.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/ExecutionRuntimeManager.java
@@ -16,10 +16,7 @@
*/
package org.apache.eagle.app.environment;
-import org.apache.eagle.app.environment.impl.SparkEnvironment;
-import org.apache.eagle.app.environment.impl.SparkExecutionRuntime;
-import org.apache.eagle.app.environment.impl.StormEnvironment;
-import org.apache.eagle.app.environment.impl.StormExecutionRuntime;
+import org.apache.eagle.app.environment.impl.*;
import com.google.common.base.Preconditions;
import com.typesafe.config.Config;
import org.slf4j.Logger;
@@ -42,6 +39,7 @@ public class ExecutionRuntimeManager {
static {
getInstance().register(StormEnvironment.class, new StormExecutionRuntime.Provider());
getInstance().register(SparkEnvironment.class, new SparkExecutionRuntime.Provider());
+ getInstance().register(WebEnvironment.class, new WebExecutionRuntime.Provider());
}
private final Map<Class<? extends Environment>, ExecutionRuntimeProvider> executionRuntimeProviders;
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebEnvironment.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebEnvironment.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebEnvironment.java
new file mode 100644
index 0000000..2bb8dc7
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebEnvironment.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.environment.impl;
+
+import com.typesafe.config.Config;
+import org.apache.eagle.app.environment.Environment;
+import org.apache.eagle.app.sink.StreamSinkProvider;
+
+public class WebEnvironment implements Environment {
+ private final Config config;
+
+ public WebEnvironment(Config config) {
+ this.config = config;
+ }
+
+ @Override
+ public Config config() {
+ return this.config;
+ }
+
+ @Override
+ public StreamSinkProvider streamSink() {
+ throw new IllegalStateException("streamSink() is not supported in " + WebEnvironment.class.getSimpleName());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebExecutionContainer.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebExecutionContainer.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebExecutionContainer.java
new file mode 100644
index 0000000..6ca7128
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebExecutionContainer.java
@@ -0,0 +1,34 @@
+/*
+ * 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.environment.impl;
+
+import org.apache.eagle.app.StaticWebApplication;
+
+/**
+ * Web Application Container.
+ */
+public class WebExecutionContainer {
+ private final StaticWebApplication webApplication;
+
+ public WebExecutionContainer(StaticWebApplication webApplication) {
+ this.webApplication = webApplication;
+ }
+
+ public StaticWebApplication getWebApplication() {
+ return webApplication;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebExecutionRuntime.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebExecutionRuntime.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebExecutionRuntime.java
new file mode 100644
index 0000000..f8eecef
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/environment/impl/WebExecutionRuntime.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * <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.environment.impl;
+
+import com.typesafe.config.Config;
+import org.apache.eagle.app.Application;
+import org.apache.eagle.app.environment.ExecutionRuntime;
+import org.apache.eagle.app.environment.ExecutionRuntimeProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * WebExecutionRuntime.
+ */
+public class WebExecutionRuntime implements ExecutionRuntime<WebEnvironment,WebExecutionContainer> {
+ private static final Logger LOGGER = LoggerFactory.getLogger(WebExecutionRuntime.class);
+
+ private WebEnvironment environment;
+
+ @Override
+ public void prepare(WebEnvironment environment) {
+ this.environment = environment;
+ }
+
+ @Override
+ public WebEnvironment environment() {
+ return this.environment;
+ }
+
+ @Override
+ public void start(Application<WebEnvironment, WebExecutionContainer> executor, Config config) {
+ LOGGER.warn("Starting {}, do nothing",executor);
+ }
+
+ @Override
+ public void stop(Application<WebEnvironment, WebExecutionContainer> executor, Config config) {
+ LOGGER.warn("Stopping {}, do nothing",executor);
+ }
+
+ @Override
+ public void status(Application<WebEnvironment, WebExecutionContainer> executor, Config config) {
+ LOGGER.warn("Checking status {}, do nothing",executor);
+ }
+
+ public static class Provider implements ExecutionRuntimeProvider<WebEnvironment,WebExecutionContainer> {
+ @Override
+ public ExecutionRuntime<WebEnvironment, WebExecutionContainer> get() {
+ return new WebExecutionRuntime();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/package-info.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/package-info.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/package-info.java
index 13cf0c9..b91a70c 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/package-info.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/package-info.java
@@ -20,7 +20,7 @@
* <h1>Application Management Framework Interfaces</h1>
*
* <ul>
- * <li>Application Context (Runtime): org.apache.eagle.app.service.ApplicationContext</li>
+ * <li>Application Context (Runtime): org.apache.eagle.app.service.ApplicationOperationContext</li>
* <li>Application Metadata Entity (Persistence): org.apache.eagle.metadata.model.ApplicationEntity</li>
* <li>Application Processing Logic (Execution): org.apache.eagle.app.Application</li>
* <li>Application Lifecycle Listener (Callback): org.apache.eagle.app.ApplicationLifecycle</li>
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationContext.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationContext.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationContext.java
deleted file mode 100644
index f7f895e..0000000
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationContext.java
+++ /dev/null
@@ -1,149 +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.service;
-
-import org.apache.eagle.alert.coordination.model.Kafka2TupleMetadata;
-import org.apache.eagle.alert.coordination.model.Tuple2StreamMetadata;
-import org.apache.eagle.alert.engine.coordinator.StreamDefinition;
-import org.apache.eagle.alert.engine.scheme.JsonScheme;
-import org.apache.eagle.alert.engine.scheme.JsonStringStreamNameSelector;
-import org.apache.eagle.alert.metadata.IMetadataDao;
-import org.apache.eagle.app.Application;
-import org.apache.eagle.app.ApplicationLifecycle;
-import org.apache.eagle.app.environment.ExecutionRuntime;
-import org.apache.eagle.app.environment.ExecutionRuntimeManager;
-import org.apache.eagle.app.sink.KafkaStreamSinkConfig;
-import org.apache.eagle.metadata.model.ApplicationEntity;
-import org.apache.eagle.metadata.model.StreamDesc;
-import org.apache.eagle.metadata.model.StreamSinkConfig;
-import com.google.common.base.Preconditions;
-import com.typesafe.config.Config;
-import com.typesafe.config.ConfigFactory;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.stream.Collectors;
-
-/**
- * Managed Application Interface: org.apache.eagle.app.service.ApplicationContext
- * <ul>
- * <li>Application Metadata Entity (Persistence): org.apache.eagle.metadata.model.ApplicationEntity</li>
- * <li>Application Processing Logic (Execution): org.apache.eagle.app.Application</li>
- * <li>Application Lifecycle Listener (Installation): org.apache.eagle.app.ApplicationLifecycle</li>
- * </ul>
- */
-public class ApplicationContext implements Serializable, ApplicationLifecycle {
- private final Config config;
- private final Application application;
- private final ExecutionRuntime runtime;
- private final ApplicationEntity metadata;
- private final IMetadataDao alertMetadataService;
-
- /**
- * @param metadata ApplicationEntity.
- * @param application Application.
- */
- public ApplicationContext(Application application, ApplicationEntity metadata, Config envConfig, IMetadataDao alertMetadataService) {
- Preconditions.checkNotNull(application, "Application is null");
- Preconditions.checkNotNull(metadata, "ApplicationEntity is null");
- this.application = application;
- this.metadata = metadata;
- this.runtime = ExecutionRuntimeManager.getInstance().getRuntime(application.getEnvironmentType(), envConfig);
- Map<String, Object> executionConfig = metadata.getConfiguration();
- if (executionConfig == null) {
- executionConfig = Collections.emptyMap();
- }
-
- // TODO: Decouple hardcoded configuration key
- executionConfig.put("siteId", metadata.getSite().getSiteId());
- executionConfig.put("mode", metadata.getMode().name());
- executionConfig.put("appId", metadata.getAppId());
- executionConfig.put("jarPath", metadata.getJarPath());
- this.config = ConfigFactory.parseMap(executionConfig).withFallback(envConfig);
- this.alertMetadataService = alertMetadataService;
- }
-
- @Override
- public void onInstall() {
- if (metadata.getDescriptor().getStreams() != null) {
- List<StreamDesc> streamDescCollection = metadata.getDescriptor().getStreams().stream().map((streamDefinition -> {
- StreamSinkConfig streamSinkConfig = this.runtime.environment().streamSink().getSinkConfig(streamDefinition.getStreamId(), this.config);
- StreamDesc streamDesc = new StreamDesc();
- streamDesc.setSchema(streamDefinition);
- streamDesc.setSink(streamSinkConfig);
- streamDesc.setStreamId(streamDefinition.getStreamId());
- return streamDesc;
- })).collect(Collectors.toList());
- metadata.setStreams(streamDescCollection);
-
- // iterate each stream descriptor and create alert datasource for each
- for (StreamDesc streamDesc : streamDescCollection) {
- // only take care of Kafka sink
- if (streamDesc.getSink() instanceof KafkaStreamSinkConfig) {
- KafkaStreamSinkConfig kafkaCfg = (KafkaStreamSinkConfig) streamDesc.getSink();
- Kafka2TupleMetadata datasource = new Kafka2TupleMetadata();
- datasource.setType("KAFKA");
- datasource.setName(metadata.getAppId());
- datasource.setTopic(kafkaCfg.getTopicId());
- datasource.setSchemeCls(JsonScheme.class.getCanonicalName());
- Tuple2StreamMetadata tuple2Stream = new Tuple2StreamMetadata();
- Properties prop = new Properties();
- prop.put(JsonStringStreamNameSelector.USER_PROVIDED_STREAM_NAME_PROPERTY, streamDesc.getStreamId());
- tuple2Stream.setStreamNameSelectorProp(prop);
- tuple2Stream.setTimestampColumn("timestamp");
- tuple2Stream.setStreamNameSelectorCls(JsonStringStreamNameSelector.class.getCanonicalName());
- datasource.setCodec(tuple2Stream);
- alertMetadataService.addDataSource(datasource);
-
- StreamDefinition sd = streamDesc.getSchema();
- sd.setDataSource(metadata.getAppId());
- alertMetadataService.createStream(streamDesc.getSchema());
- }
- }
- }
- }
-
- @Override
- public void onUninstall() {
- // we should remove alert data source and stream definition while we do uninstall
- if (metadata.getStreams() == null) {
- return;
- }
- // iterate each stream descriptor and create alert datasource for each
- for (StreamDesc streamDesc : metadata.getStreams()) {
- alertMetadataService.removeDataSource(metadata.getAppId());
- alertMetadataService.removeStream(streamDesc.getStreamId());
- }
- }
-
- @Override
- public void onStart() {
- this.runtime.start(this.application, this.config);
- }
-
- @Override
- public void onStop() {
- this.runtime.stop(this.application, this.config);
- }
-
- public ApplicationEntity getMetadata() {
- return metadata;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationOperationContext.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationOperationContext.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationOperationContext.java
new file mode 100644
index 0000000..82ca659
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationOperationContext.java
@@ -0,0 +1,153 @@
+/*
+ * 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.alert.coordination.model.Kafka2TupleMetadata;
+import org.apache.eagle.alert.coordination.model.Tuple2StreamMetadata;
+import org.apache.eagle.alert.engine.coordinator.StreamDefinition;
+import org.apache.eagle.alert.engine.scheme.JsonScheme;
+import org.apache.eagle.alert.engine.scheme.JsonStringStreamNameSelector;
+import org.apache.eagle.alert.metadata.IMetadataDao;
+import org.apache.eagle.app.Application;
+import org.apache.eagle.app.ApplicationLifecycle;
+import org.apache.eagle.app.StaticWebApplication;
+import org.apache.eagle.app.environment.ExecutionRuntime;
+import org.apache.eagle.app.environment.ExecutionRuntimeManager;
+import org.apache.eagle.app.sink.KafkaStreamSinkConfig;
+import org.apache.eagle.metadata.model.ApplicationEntity;
+import org.apache.eagle.metadata.model.StreamDesc;
+import org.apache.eagle.metadata.model.StreamSinkConfig;
+import com.google.common.base.Preconditions;
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+/**
+ * Managed Application Interface: org.apache.eagle.app.service.ApplicationOperationContext
+ * <ul>
+ * <li>Application Metadata Entity (Persistence): org.apache.eagle.metadata.model.ApplicationEntity</li>
+ * <li>Application Processing Logic (Execution): org.apache.eagle.app.Application</li>
+ * <li>Application Lifecycle Listener (Installation): org.apache.eagle.app.ApplicationLifecycle</li>
+ * </ul>
+ */
+public class ApplicationOperationContext implements Serializable, ApplicationLifecycle {
+ private final Config config;
+ private final Application application;
+ private final ExecutionRuntime runtime;
+ private final ApplicationEntity metadata;
+ private final IMetadataDao alertMetadataService;
+
+ /**
+ * @param metadata ApplicationEntity.
+ * @param application Application.
+ */
+ public ApplicationOperationContext(Application application, ApplicationEntity metadata, Config envConfig, IMetadataDao alertMetadataService) {
+ Preconditions.checkNotNull(application, "Application is null");
+ Preconditions.checkNotNull(metadata, "ApplicationEntity is null");
+ this.application = application;
+ this.metadata = metadata;
+ this.runtime = ExecutionRuntimeManager.getInstance().getRuntime(application.getEnvironmentType(), envConfig);
+ Map<String, Object> executionConfig = metadata.getConfiguration();
+ if (executionConfig == null) {
+ executionConfig = Collections.emptyMap();
+ }
+
+ // TODO: Decouple hardcoded configuration key
+ executionConfig.put("siteId", metadata.getSite().getSiteId());
+ executionConfig.put("mode", metadata.getMode().name());
+ executionConfig.put("appId", metadata.getAppId());
+ executionConfig.put("jarPath", metadata.getJarPath());
+ this.config = ConfigFactory.parseMap(executionConfig).withFallback(envConfig);
+ this.alertMetadataService = alertMetadataService;
+ }
+
+ @Override
+ public void onInstall() {
+ metadata.setExecutable(application.isExecutable());
+ if (metadata.getDescriptor().getStreams() != null) {
+ List<StreamDesc> streamDescCollection = metadata.getDescriptor().getStreams().stream().map((streamDefinition -> {
+ StreamSinkConfig streamSinkConfig = this.runtime.environment().streamSink().getSinkConfig(streamDefinition.getStreamId(), this.config);
+ StreamDesc streamDesc = new StreamDesc();
+ streamDesc.setSchema(streamDefinition);
+ streamDesc.setSink(streamSinkConfig);
+ streamDesc.setStreamId(streamDefinition.getStreamId());
+ return streamDesc;
+ })).collect(Collectors.toList());
+ metadata.setStreams(streamDescCollection);
+
+ // iterate each stream descriptor and create alert datasource for each
+ for (StreamDesc streamDesc : streamDescCollection) {
+ // only take care of Kafka sink
+ if (streamDesc.getSink() instanceof KafkaStreamSinkConfig) {
+ KafkaStreamSinkConfig kafkaCfg = (KafkaStreamSinkConfig) streamDesc.getSink();
+ Kafka2TupleMetadata datasource = new Kafka2TupleMetadata();
+ datasource.setType("KAFKA");
+ datasource.setName(metadata.getAppId());
+ datasource.setTopic(kafkaCfg.getTopicId());
+ datasource.setSchemeCls(JsonScheme.class.getCanonicalName());
+ Tuple2StreamMetadata tuple2Stream = new Tuple2StreamMetadata();
+ Properties prop = new Properties();
+ prop.put(JsonStringStreamNameSelector.USER_PROVIDED_STREAM_NAME_PROPERTY, streamDesc.getStreamId());
+ tuple2Stream.setStreamNameSelectorProp(prop);
+ tuple2Stream.setTimestampColumn("timestamp");
+ tuple2Stream.setStreamNameSelectorCls(JsonStringStreamNameSelector.class.getCanonicalName());
+ datasource.setCodec(tuple2Stream);
+ alertMetadataService.addDataSource(datasource);
+
+ StreamDefinition sd = streamDesc.getSchema();
+ sd.setDataSource(metadata.getAppId());
+ alertMetadataService.createStream(streamDesc.getSchema());
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onUninstall() {
+ // we should remove alert data source and stream definition while we do uninstall
+ if (metadata.getStreams() == null) {
+ return;
+ }
+ // iterate each stream descriptor and create alert datasource for each
+ for (StreamDesc streamDesc : metadata.getStreams()) {
+ alertMetadataService.removeDataSource(metadata.getAppId());
+ alertMetadataService.removeStream(streamDesc.getStreamId());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void onStart() {
+ this.runtime.start(this.application, this.config);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void onStop() {
+ this.runtime.stop(this.application, this.config);
+ }
+
+ public ApplicationEntity getMetadata() {
+ return metadata;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationProviderLoader.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationProviderLoader.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationProviderLoader.java
index d526bd4..11e5dca 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationProviderLoader.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/ApplicationProviderLoader.java
@@ -60,7 +60,7 @@ public abstract class ApplicationProviderLoader {
if (providers.containsKey(type)) {
return providers.get(type);
} else {
- throw new IllegalArgumentException("Unknown Application Type: " + type);
+ throw new IllegalArgumentException("Illegal Application Type: " + type);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationManagementServiceImpl.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationManagementServiceImpl.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationManagementServiceImpl.java
index 14abbc3..fd8e650 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationManagementServiceImpl.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationManagementServiceImpl.java
@@ -16,23 +16,20 @@
*/
package org.apache.eagle.app.service.impl;
+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.alert.metadata.IMetadataDao;
-import org.apache.eagle.app.service.ApplicationContext;
import org.apache.eagle.app.service.ApplicationManagementService;
import org.apache.eagle.app.service.ApplicationOperations;
+import org.apache.eagle.app.service.ApplicationOperationContext;
import org.apache.eagle.app.service.ApplicationProviderService;
import org.apache.eagle.app.spi.ApplicationProvider;
import org.apache.eagle.metadata.exceptions.EntityNotFoundException;
-import org.apache.eagle.metadata.model.ApplicationDesc;
-import org.apache.eagle.metadata.model.ApplicationEntity;
-import org.apache.eagle.metadata.model.Property;
-import org.apache.eagle.metadata.model.SiteEntity;
+import org.apache.eagle.metadata.model.*;
import org.apache.eagle.metadata.service.ApplicationEntityService;
import org.apache.eagle.metadata.service.SiteEntityService;
-import com.google.common.base.Preconditions;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import com.typesafe.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -81,63 +78,80 @@ public class ApplicationManagementServiceImpl implements ApplicationManagementSe
applicationEntity.setJarPath(operation.getJarPath());
applicationEntity.ensureDefault();
- /**
- * calculate application config based on
- * 1) default values in metadata.xml
- * 2) user's config value override default configurations
- * 3) some metadata, for example siteId, mode, appId in ApplicationContext
- */
+ // Calculate application config based on:
+ //
+ // 1) default values in metadata.xml.
+ // 2) user's config value override default configurations.
+ // 3) fill runtime information, for example siteId, mode, appId in ApplicationOperationContext.
+
Map<String, Object> appConfig = new HashMap<>();
ApplicationProvider provider = applicationProviderService.getApplicationProviderByType(operation.getAppType());
- List<Property> propertyList = provider.getApplicationDesc().getConfiguration().getProperties();
- for (Property p : propertyList) {
- appConfig.put(p.getName(), p.getValue());
- }
- if (operation.getConfiguration() != null) {
- appConfig.putAll(operation.getConfiguration());
+ ApplicationDesc applicationDesc = provider.getApplicationDesc();
+
+ if (applicationDesc.getConfiguration() != null) {
+ List<Property> propertyList = provider.getApplicationDesc().getConfiguration().getProperties();
+ for (Property p : propertyList) {
+ appConfig.put(p.getName(), p.getValue());
+ }
+ if (operation.getConfiguration() != null) {
+ appConfig.putAll(operation.getConfiguration());
+ }
}
applicationEntity.setConfiguration(appConfig);
- ApplicationContext applicationContext = new ApplicationContext(
+
+ validateDependingApplicationInstalled(applicationEntity);
+
+ ApplicationOperationContext applicationOperationContext = new ApplicationOperationContext(
applicationProviderService.getApplicationProviderByType(applicationEntity.getDescriptor().getType()).getApplication(),
applicationEntity, config, alertMetadataService);
- applicationContext.onInstall();
+ applicationOperationContext.onInstall();
return applicationEntityService.create(applicationEntity);
}
+ private void validateDependingApplicationInstalled(ApplicationEntity applicationEntity) {
+ if (applicationEntity.getDescriptor().getDependencies() != null) {
+ for (ApplicationDependency dependency : applicationEntity.getDescriptor().getDependencies()) {
+ if (dependency.isRequired() && applicationEntityService.getBySiteIdAndAppType(applicationEntity.getSite().getSiteId(), dependency.getType()) == null) {
+ throw new IllegalStateException("Required dependency " + dependency.toString() + " of " + applicationEntity.getDescriptor().getType() + " was not installed");
+ }
+ }
+ }
+ }
+
@Override
public ApplicationEntity uninstall(ApplicationOperations.UninstallOperation operation) {
ApplicationEntity applicationEntity = applicationEntityService.getByUUIDOrAppId(operation.getUuid(), operation.getAppId());
- ApplicationContext applicationContext = new ApplicationContext(
+ ApplicationOperationContext applicationOperationContext = new ApplicationOperationContext(
applicationProviderService.getApplicationProviderByType(applicationEntity.getDescriptor().getType()).getApplication(),
applicationEntity, config, alertMetadataService);
// TODO: Check status, skip stop if already STOPPED
try {
- applicationContext.onStop();
+ applicationOperationContext.onStop();
} catch (Throwable throwable) {
LOGGER.error(throwable.getMessage(), throwable);
}
- applicationContext.onUninstall();
+ applicationOperationContext.onUninstall();
return applicationEntityService.delete(applicationEntity);
}
@Override
public ApplicationEntity start(ApplicationOperations.StartOperation operation) {
ApplicationEntity applicationEntity = applicationEntityService.getByUUIDOrAppId(operation.getUuid(), operation.getAppId());
- ApplicationContext applicationContext = new ApplicationContext(
+ ApplicationOperationContext applicationOperationContext = new ApplicationOperationContext(
applicationProviderService.getApplicationProviderByType(applicationEntity.getDescriptor().getType()).getApplication(),
applicationEntity, config, alertMetadataService);
- applicationContext.onStart();
+ applicationOperationContext.onStart();
return applicationEntity;
}
@Override
public ApplicationEntity stop(ApplicationOperations.StopOperation operation) {
ApplicationEntity applicationEntity = applicationEntityService.getByUUIDOrAppId(operation.getUuid(), operation.getAppId());
- ApplicationContext applicationContext = new ApplicationContext(
+ ApplicationOperationContext applicationOperationContext = new ApplicationOperationContext(
applicationProviderService.getApplicationProviderByType(applicationEntity.getDescriptor().getType()).getApplication(),
applicationEntity, config, alertMetadataService);
- applicationContext.onStop();
+ applicationOperationContext.onStop();
return applicationEntity;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderConfigLoader.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderConfigLoader.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderConfigLoader.java
index 2f613c1..025bc7c 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderConfigLoader.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderConfigLoader.java
@@ -31,6 +31,10 @@ import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
+/**
+ * @deprecated unstable implementation.
+ */
+@Deprecated
public class ApplicationProviderConfigLoader extends ApplicationProviderLoader {
public static final String DEFAULT_APPLICATIONS_CONFIG_FILE = "providers.xml";
private static final String APPLICATIONS_CONFIG_PROPS_KEY = "application.provider.config";
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderSPILoader.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderSPILoader.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderSPILoader.java
index 8b73865..1e0421a 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderSPILoader.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderSPILoader.java
@@ -30,6 +30,9 @@ import java.net.URLClassLoader;
import java.util.ServiceLoader;
import java.util.function.Function;
+/**
+ * Load Application Provider with SPI, by default from current class loader.
+ */
public class ApplicationProviderSPILoader extends ApplicationProviderLoader {
private final String appProviderExtDir;
private static final Logger LOG = LoggerFactory.getLogger(ApplicationProviderSPILoader.class);
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderServiceImpl.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderServiceImpl.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderServiceImpl.java
index 3cb31f9..1aa4618 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderServiceImpl.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/service/impl/ApplicationProviderServiceImpl.java
@@ -16,17 +16,20 @@
*/
package org.apache.eagle.app.service.impl;
+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.service.ApplicationProviderLoader;
import org.apache.eagle.app.service.ApplicationProviderService;
import org.apache.eagle.app.spi.ApplicationProvider;
+import org.apache.eagle.metadata.model.ApplicationDependency;
import org.apache.eagle.metadata.model.ApplicationDesc;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import com.typesafe.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
+import java.util.List;
import java.util.stream.Collectors;
/**
@@ -39,7 +42,7 @@ public class ApplicationProviderServiceImpl implements ApplicationProviderServic
private final Config config;
private static final Logger LOG = LoggerFactory.getLogger(ApplicationProviderServiceImpl.class);
private final ApplicationProviderLoader appProviderLoader;
- public static final String APP_PROVIDER_LOADER_CLASS_KEY = "application.provider.loader";
+ private static final String APP_PROVIDER_LOADER_CLASS_KEY = "application.provider.loader";
@Inject
public ApplicationProviderServiceImpl(Config config) {
@@ -67,6 +70,47 @@ public class ApplicationProviderServiceImpl implements ApplicationProviderServic
LOG.warn("Loading application providers ...");
appProviderLoader.load();
LOG.warn("Loaded {} application providers", appProviderLoader.getProviders().size());
+ validate();
+ }
+
+ private void validate() {
+ for (ApplicationDesc applicationDesc : getApplicationDescs()) {
+ LOG.debug("Validating {}", applicationDesc.getType());
+
+ Preconditions.checkNotNull(applicationDesc.getType(), "type is null in " + applicationDesc);
+ Preconditions.checkNotNull(applicationDesc.getVersion(), "version is null in " + applicationDesc);
+ Preconditions.checkNotNull(applicationDesc.getName(), "name is null in " + applicationDesc);
+
+ // Validate Dependency
+ LOG.debug("Validating dependency of {}", applicationDesc.getType());
+ List<ApplicationDependency> dependencyList = applicationDesc.getDependencies();
+ if (dependencyList != null) {
+ for (ApplicationDependency dependency : dependencyList) {
+ try {
+ ApplicationDesc dependencyDesc = getApplicationDescByType(dependency.getType());
+ if (dependencyDesc != null && dependency.getVersion() != null) {
+ if (dependencyDesc.getVersion().equals(dependency.getVersion())) {
+ LOG.debug("Loaded dependency {} -> {}", applicationDesc.getType(), dependency);
+ } else {
+ LOG.warn("Loaded dependency {} -> {}, but the version was mismatched, expected: {}, actual: {}",
+ applicationDesc.getType(), dependency, dependency.getVersion(), applicationDesc.getVersion());
+ }
+ } else {
+ assert dependencyDesc != null;
+ dependency.setVersion(dependencyDesc.getVersion());
+ }
+ } catch (IllegalArgumentException ex) {
+ if (!dependency.isRequired()) {
+ LOG.warn("Unable to load dependency {} -> {}", applicationDesc.getType(), dependency, ex);
+ } else {
+ LOG.error("Failed to load dependency {} -> {}", applicationDesc.getType(), dependency,ex);
+ throw new IllegalStateException("Failed to load application providers due to dependency missing",ex);
+ }
+ }
+ }
+ }
+ LOG.info("Validated {} successfully", applicationDesc.getType());
+ }
}
public Collection<ApplicationProvider> getProviders() {
@@ -81,7 +125,6 @@ public class ApplicationProviderServiceImpl implements ApplicationProviderServic
return appProviderLoader.getApplicationProviderByType(type);
}
- @Deprecated
public ApplicationDesc getApplicationDescByType(String appType) {
return appProviderLoader.getApplicationProviderByType(appType).getApplicationDesc();
}
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/AbstractApplicationProvider.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/AbstractApplicationProvider.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/AbstractApplicationProvider.java
index 4a9c1ff..06ac703 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/AbstractApplicationProvider.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/AbstractApplicationProvider.java
@@ -14,73 +14,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.apache.eagle.app.spi;
import org.apache.eagle.alert.engine.coordinator.StreamDefinition;
import org.apache.eagle.app.Application;
-import org.apache.eagle.app.config.ApplicationProviderConfig;
-import org.apache.eagle.app.config.ApplicationProviderDescConfig;
import org.apache.eagle.common.module.ModuleRegistry;
import org.apache.eagle.metadata.model.ApplicationDesc;
import org.apache.eagle.metadata.model.ApplicationDocs;
import org.apache.eagle.metadata.model.Configuration;
-import com.typesafe.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.List;
import javax.xml.bind.JAXBException;
+import java.util.List;
/**
- * Default metadata path is: /META-INF/providers/${ApplicationProviderClassName}.xml
- *
- * @param <T>
+ * Describe Application metadata with XML descriptor configuration in path of: /META-INF/providers/${ApplicationProviderClassName}.xml
*/
public abstract class AbstractApplicationProvider<T extends Application> implements ApplicationProvider<T> {
private static final Logger LOG = LoggerFactory.getLogger(AbstractApplicationProvider.class);
private final ApplicationDesc applicationDesc;
- private static final String METADATA_RESOURCE_PATH = "/META-INF/providers/%s.xml";
-
- /**
- * Default metadata path is: /META-INF/providers/${ApplicationProviderClassName}.xml
- *
- * <p>You are not recommended to override this method except you could make sure the path is universal unique</p>
- *
- * @return metadata file path
- */
- protected final String getMetadata() {
- return String.format(METADATA_RESOURCE_PATH, this.getClass().getName());
- }
-
protected AbstractApplicationProvider() {
- String applicationDescConfig = getMetadata();
- applicationDesc = new ApplicationDesc();
- applicationDesc.setProviderClass(this.getClass());
- ApplicationProviderDescConfig descWrapperConfig = ApplicationProviderDescConfig.loadFromXML(this.getClass(), applicationDescConfig);
- setType(descWrapperConfig.getType());
- setVersion(descWrapperConfig.getVersion());
- setName(descWrapperConfig.getName());
- setDocs(descWrapperConfig.getDocs());
- try {
- if (descWrapperConfig.getAppClass() != null) {
- // setAppClass((Class<T>) Class.forName(descWrapperConfig.getAppClass()));
- setAppClass((Class<T>) Class.forName(descWrapperConfig.getAppClass(), true, this.getClass().getClassLoader()));
- if (!Application.class.isAssignableFrom(applicationDesc.getAppClass())) {
- throw new IllegalStateException(descWrapperConfig.getAppClass() + " is not sub-class of " + Application.class.getCanonicalName());
- }
- }
- } catch (ClassNotFoundException e) {
- LOG.error(e.getMessage(), e);
- throw new RuntimeException(e.getMessage(), e.getCause());
- }
- setViewPath(descWrapperConfig.getViewPath());
- setConfiguration(descWrapperConfig.getConfiguration());
- setStreams(descWrapperConfig.getStreams());
- }
-
- @Override
- public void prepare(ApplicationProviderConfig providerConfig, Config envConfig) {
+ applicationDesc = new ApplicationXMLDescriptorLoader(this.getClass(),this.getApplicationClass()).getApplicationDesc();
}
protected void setVersion(String version) {
@@ -116,7 +73,8 @@ public abstract class AbstractApplicationProvider<T extends Application> impleme
public String toString() {
return String.format(
"%s[name=%s, type=%s, version=%s, viewPath=%s, appClass=%s, configuration= %s properties]", getClass().getSimpleName(),
- applicationDesc.getName(), applicationDesc.getType(), applicationDesc.getVersion(), applicationDesc.getViewPath(), applicationDesc.getAppClass(), applicationDesc.getConfiguration().size()
+ applicationDesc.getName(), applicationDesc.getType(), applicationDesc.getVersion(), applicationDesc.getViewPath(), applicationDesc.getAppClass(),
+ applicationDesc.getConfiguration() == null ? 0 : applicationDesc.getConfiguration().size()
);
}
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationDescLoader.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationDescLoader.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationDescLoader.java
new file mode 100644
index 0000000..ecab289
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationDescLoader.java
@@ -0,0 +1,27 @@
+/*
+ * 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.spi;
+
+import org.apache.eagle.metadata.model.ApplicationDesc;
+
+public interface ApplicationDescLoader {
+
+ /**
+ * @return ApplicationDesc instance.
+ */
+ ApplicationDesc getApplicationDesc();
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationProvider.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationProvider.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationProvider.java
index 761cfbb..0dceb72 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationProvider.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationProvider.java
@@ -16,15 +16,27 @@
*/
package org.apache.eagle.app.spi;
+import com.typesafe.config.Config;
import org.apache.eagle.app.Application;
import org.apache.eagle.app.config.ApplicationProviderConfig;
import org.apache.eagle.common.module.ModuleRegistry;
import org.apache.eagle.metadata.model.ApplicationDesc;
-import com.typesafe.config.Config;
+import java.lang.reflect.ParameterizedType;
+
+/**
+ * Application Service Provider Interface.
+ *
+ * @param <T> Application Type.
+ */
public interface ApplicationProvider<T extends Application> {
- void prepare(ApplicationProviderConfig providerConfig,Config envConfig);
+ /**
+ * Prepare Application Provider before loading.
+ */
+ default void prepare(ApplicationProviderConfig providerConfig, Config envConfig) {
+ // Do nothing by default.
+ }
/**
* @return application descriptor.
@@ -32,9 +44,30 @@ public interface ApplicationProvider<T extends Application> {
ApplicationDesc getApplicationDesc();
/**
+ * Get Application Instance Type, by default load from generic parameter automatically
+ *
+ * @return application class type if exists.
+ */
+ default Class<T> getApplicationClass() {
+ try {
+ String className = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].getTypeName();
+ Class<?> clazz = Class.forName(className);
+ return (Class<T>) clazz;
+ } catch (Exception e) {
+ throw new IllegalStateException(
+ "Unable to get generic application class, "
+ + "reason: class is not parametrized with generic type, "
+ + "please provide application class by overriding getApplicationClass()");
+ }
+ }
+
+ /**
* @return application instance.
*/
T getApplication();
+ /**
+ * Extend application modules like Web Resource, Metadata Store, etc.
+ */
void register(ModuleRegistry registry);
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationXMLDescriptorLoader.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationXMLDescriptorLoader.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationXMLDescriptorLoader.java
new file mode 100644
index 0000000..bdc8a3a
--- /dev/null
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/spi/ApplicationXMLDescriptorLoader.java
@@ -0,0 +1,69 @@
+/*
+ * 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.spi;
+
+import org.apache.eagle.app.Application;
+import org.apache.eagle.app.config.ApplicationProviderDescConfig;
+import org.apache.eagle.metadata.model.ApplicationDesc;
+
+/**
+ * Describe Application metadata with XML descriptor configuration in path of: /META-INF/providers/${ApplicationProviderClassName}.xml
+ */
+class ApplicationXMLDescriptorLoader implements ApplicationDescLoader {
+ private final Class<? extends ApplicationProvider> providerClass;
+ private final Class<? extends Application> applicationClass;
+
+ private static final String METADATA_RESOURCE_PATH = "/META-INF/providers/%s.xml";
+
+ ApplicationXMLDescriptorLoader(Class<? extends ApplicationProvider> providerClass, Class<? extends Application> applicationClass) {
+ this.providerClass = providerClass;
+ this.applicationClass = applicationClass;
+ }
+
+ /**
+ * Default metadata path is: /META-INF/providers/${ApplicationProviderClassName}.xml
+ * <p>You are not recommended to override this method except you could make sure the path is universal unique</p>
+ *
+ * @return metadata file path
+ */
+ private String generateXMLDescriptorPath() {
+ return String.format(METADATA_RESOURCE_PATH, providerClass.getName());
+ }
+
+ @Override
+ public ApplicationDesc getApplicationDesc() {
+ String descriptorPath = generateXMLDescriptorPath();
+ ApplicationDesc applicationDesc = new ApplicationDesc();
+ applicationDesc.setProviderClass(this.getClass());
+ ApplicationProviderDescConfig descWrapperConfig = ApplicationProviderDescConfig.loadFromXML(this.getClass(), descriptorPath);
+ applicationDesc.setType(descWrapperConfig.getType());
+ applicationDesc.setVersion(descWrapperConfig.getVersion());
+ applicationDesc.setName(descWrapperConfig.getName());
+ applicationDesc.setDocs(descWrapperConfig.getDocs());
+ if (applicationClass != null) {
+ applicationDesc.setAppClass(applicationClass);
+ if (!Application.class.isAssignableFrom(applicationDesc.getAppClass())) {
+ throw new IllegalStateException(applicationDesc.getAppClass() + " is not sub-class of " + Application.class.getCanonicalName());
+ }
+ }
+ applicationDesc.setDependencies(descWrapperConfig.getDependencies());
+ applicationDesc.setViewPath(descWrapperConfig.getViewPath());
+ applicationDesc.setConfiguration(descWrapperConfig.getConfiguration());
+ applicationDesc.setStreams(descWrapperConfig.getStreams());
+ return applicationDesc;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/ApplicationProviderDescConfigTest.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/ApplicationProviderDescConfigTest.java b/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/ApplicationProviderDescConfigTest.java
index 9285d7d..992c622 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/ApplicationProviderDescConfigTest.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/ApplicationProviderDescConfigTest.java
@@ -1,16 +1,4 @@
-package org.apache.eagle.app;
-
-import org.apache.eagle.app.config.ApplicationProviderDescConfig;
-import org.apache.eagle.app.spi.AbstractApplicationProvider;
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Unmarshaller;
-import java.io.InputStream;
-
-/**
+/*
* 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.
@@ -26,13 +14,17 @@ import java.io.InputStream;
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package org.apache.eagle.app;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import java.io.InputStream;
+
+
public class ApplicationProviderDescConfigTest {
- @Test
- @Ignore
- public void testApplicationDescWrapperConfigLoadFromXML(){
- ApplicationProviderDescConfig config = ApplicationProviderDescConfig.loadFromXML(ApplicationProviderDescConfigTest.class, "TestApplicationMetadata.xml");
- Assert.assertNotNull(config);
- }
@Test
public void testStreamDefinitionLoadFromXML(){
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/ApplicationProviderServiceTest.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/ApplicationProviderServiceTest.java b/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/ApplicationProviderServiceTest.java
index 6f32521..57337f5 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/ApplicationProviderServiceTest.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/ApplicationProviderServiceTest.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.
@@ -16,34 +16,36 @@
*/
package org.apache.eagle.app;
+import static org.junit.Assert.*;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.typesafe.config.ConfigFactory;
-import org.apache.eagle.app.module.ApplicationGuiceModule;
+import com.google.inject.Inject;
import org.apache.eagle.app.service.ApplicationProviderService;
-import org.apache.eagle.app.service.impl.ApplicationProviderServiceImpl;
import org.apache.eagle.app.spi.ApplicationProvider;
-import org.apache.eagle.common.module.CommonGuiceModule;
+import org.apache.eagle.app.test.ApplicationTestBase;
import org.apache.eagle.metadata.model.ApplicationDesc;
-import org.apache.eagle.metadata.service.memory.MemoryMetadataStore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
-public class ApplicationProviderServiceTest {
+public class ApplicationProviderServiceTest extends ApplicationTestBase {
private final static Logger LOGGER = LoggerFactory.getLogger(ApplicationProviderServiceTest.class);
- private Injector injector = Guice.createInjector(new CommonGuiceModule(),new ApplicationGuiceModule(new ApplicationProviderServiceImpl(ConfigFactory.load())), new MemoryMetadataStore());
+
+ @Inject
+ private
+ ApplicationProviderService providerManager;
@Test
- public void testApplicationProviderManagerInit(){
- ApplicationProviderService providerManager = injector.getInstance(ApplicationProviderService.class);
+ public void testApplicationProviderLoaderService(){
Collection<ApplicationDesc> applicationDescs = providerManager.getApplicationDescs();
Collection<ApplicationProvider> applicationProviders = providerManager.getProviders();
-
applicationDescs.forEach((d)-> LOGGER.debug(d.toString()));
applicationProviders.forEach((d)-> LOGGER.debug(d.toString()));
+ assertNull(providerManager.getApplicationDescByType("TEST_APPLICATION").getViewPath());
+ assertEquals("/apps/test_web_app",providerManager.getApplicationDescByType("TEST_WEB_APPLICATION").getViewPath());
+ assertNotNull(providerManager.getApplicationDescByType("TEST_WEB_APPLICATION").getDependencies());
+ assertEquals(1,providerManager.getApplicationDescByType("TEST_WEB_APPLICATION").getDependencies().size());
+ assertEquals("TEST_APPLICATION",providerManager.getApplicationDescByType("TEST_WEB_APPLICATION").getDependencies().get(0).getType());
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/83bd4e3d/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/TestStormApplication.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/TestStormApplication.java b/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/TestStormApplication.java
index 5668e6f..c6ac5db 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/TestStormApplication.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/test/java/org/apache/eagle/app/TestStormApplication.java
@@ -86,7 +86,7 @@ public class TestStormApplication extends StormApplication{
Class<? extends ExtendedDao> getType();
}
- private class ExtendedDaoImpl implements ExtendedDao {
+ private static class ExtendedDaoImpl implements ExtendedDao {
private final Config config;
@Inject