You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by om...@apache.org on 2011/12/06 17:19:15 UTC
svn commit: r1210997 [1/2] - in /incubator/ambari/trunk: ./
client/src/main/java/org/apache/ambari/common/rest/entities/ controller/
controller/src/main/java/org/apache/ambari/components/
controller/src/main/java/org/apache/ambari/components/impl/ cont...
Author: omalley
Date: Tue Dec 6 16:19:14 2011
New Revision: 1210997
URL: http://svn.apache.org/viewvc?rev=1210997&view=rev
Log:
AMBARI-147. Create a stack flattener and introduce Guice. (omalley)
Added:
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/ComponentModule.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/ComponentPluginFactory.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/impl/XmlComponentPluginFactoryImpl.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/ClusterFactory.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/ControllerModule.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/StackFlattener.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/datastore/impl/StaticDataStore.java
incubator/ambari/trunk/controller/src/main/resources/org/apache/ambari/clusters/
incubator/ambari/trunk/controller/src/main/resources/org/apache/ambari/clusters/cluster123.xml
incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/controller/
incubator/ambari/trunk/controller/src/test/java/org/apache/ambari/controller/StackFlattenerTest.java
Removed:
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/datastore/DataStoreFactory.java
Modified:
incubator/ambari/trunk/CHANGES.txt
incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Component.java
incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/ComponentDefinition.java
incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/ConfigurationCategory.java
incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Property.java
incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/RepositoryKind.java
incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Role.java
incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Stack.java
incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/StackInformation.java
incubator/ambari/trunk/controller/pom.xml
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/impl/XmlComponentDefinition.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Cluster.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Clusters.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Controller.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/HeartbeatHandler.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Nodes.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Stacks.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/agent/ControllerResource.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/resources/ClustersResource.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/resources/NodesResource.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/resources/StacksResource.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/datastore/PersistentDataStore.java
incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/datastore/impl/ZookeeperDS.java
incubator/ambari/trunk/controller/src/main/resources/org/apache/ambari/stacks/puppet1-0.xml
Modified: incubator/ambari/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Tue Dec 6 16:19:14 2011
@@ -2,6 +2,8 @@ Ambari Change log
Release 0.1.0 - unreleased
+ AMBARI-147. Create a stack flattener and introduce Guice. (omalley)
+
AMBARI-145. FSMs are created for only those components that have
active roles (Thejas M Nair via ddas)
Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Component.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Component.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Component.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Component.java Tue Dec 6 16:19:14 2011
@@ -42,45 +42,89 @@ public class Component {
* The name of the component.
*/
@XmlAttribute(required = true)
- protected String name;
+ private String name;
/**
* The architecture of the tarball/rpm to install.
*/
@XmlAttribute
- protected String architecture;
+ private String architecture;
/**
* The version of the tarball/rpm to install.
*/
@XmlAttribute
- protected String version;
+ private String version;
/**
* The provider of the tarball/rpm to install.
*/
@XmlAttribute
- protected String provider;
+ private String provider;
/**
* The definition of the component including how to configure and run
* the component.
*/
@XmlElement
- protected ComponentDefinition definition;
+ private ComponentDefinition definition;
/**
* The configuration shared between the active roles of the component.
*/
@XmlElement
- protected Configuration configuration;
+ private Configuration configuration;
/**
* Specific configuration for each of the roles.
*/
@XmlElement
- protected List<Role> roles;
+ private List<Role> roles;
+ public Component() {
+ // PASS
+ }
+
+ public Component(String name, String version, String architecture,
+ String provider, ComponentDefinition definition,
+ Configuration configuration, List<Role> roles) {
+ this.name = name;
+ this.version = version;
+ this.architecture = architecture;
+ this.provider = provider;
+ this.definition = definition;
+ this.configuration = configuration;
+ this.roles = roles;
+ }
+
+ /**
+ * Shallow copy overriding attributes of a component.
+ * @param other the component to copy
+ */
+ public void mergeInto(Component other) {
+ if (other.architecture != null) {
+ this.architecture = other.architecture;
+ }
+ if (other.configuration != null) {
+ this.configuration = other.configuration;
+ }
+ if (other.definition != null) {
+ this.definition.mergeInto(other.definition);
+ }
+ if (other.name != null) {
+ this.name = other.name;
+ }
+ if (other.provider != null) {
+ this.provider = other.provider;
+ }
+ if (other.roles != null) {
+ this.roles = other.roles;
+ }
+ if (other.version != null) {
+ this.version = other.version;
+ }
+ }
+
/**
* Gets the value of the name property.
*
Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/ComponentDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/ComponentDefinition.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/ComponentDefinition.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/ComponentDefinition.java Tue Dec 6 16:19:14 2011
@@ -29,12 +29,73 @@ import javax.xml.bind.annotation.XmlRoot
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class ComponentDefinition {
+
@XmlAttribute
- protected String provider;
+ private String provider;
@XmlAttribute
- protected String name;
+ private String name;
@XmlAttribute
- protected String version;
+ private String version;
+
+ public ComponentDefinition() {
+ // PASS
+ }
+
+ public ComponentDefinition(String name, String provider, String version) {
+ this.name = name;
+ this.provider = provider;
+ this.version = version;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == null || other.getClass() != getClass()) {
+ return false;
+ } else if (other == this) {
+ return true;
+ } else {
+ ComponentDefinition otherDefn = (ComponentDefinition) other;
+ return isStringEqual(name, otherDefn.name) &&
+ isStringEqual(provider, otherDefn.provider) &&
+ isStringEqual(version, otherDefn.version);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return stringHash(name) + stringHash(version);
+ }
+
+ static int stringHash(String str) {
+ return str != null ? str.hashCode() : 0;
+ }
+
+ static boolean isStringEqual(String left, String right) {
+ if (left == right) {
+ return true;
+ } if (left == null || right == null) {
+ return false;
+ } else {
+ return left.equals(right);
+ }
+ }
+
+ /**
+ * Override this configuration's properties with any corresponding ones
+ * that are set in the other component.
+ * @param other the overriding component
+ */
+ public void mergeInto(ComponentDefinition other) {
+ if (other.provider != null) {
+ this.provider = other.provider;
+ }
+ if (other.name != null) {
+ this.name = other.name;
+ }
+ if (other.version != null) {
+ this.version = other.version;
+ }
+ }
/**
* Get the provider that published the component definition
Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/ConfigurationCategory.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/ConfigurationCategory.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/ConfigurationCategory.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/ConfigurationCategory.java Tue Dec 6 16:19:14 2011
@@ -39,9 +39,18 @@ import javax.xml.bind.annotation.XmlType
public class ConfigurationCategory {
@XmlAttribute(required = true)
- protected String name;
+ private String name;
@XmlElements({@XmlElement})
- protected List<Property> property;
+ private List<Property> property;
+
+ public ConfigurationCategory() {
+ // PASS
+ }
+
+ public ConfigurationCategory(String name, List<Property> property) {
+ this.name = name;
+ this.property = property;
+ }
/**
* Gets the value of the name property.
Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Property.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Property.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Property.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Property.java Tue Dec 6 16:19:14 2011
@@ -42,6 +42,15 @@ public class Property {
@XmlAttribute(required = false)
protected boolean force = false;
+ public Property() {
+ // PASS
+ }
+
+ public Property(String key, String value) {
+ this.name = key;
+ this.value = value;
+ }
+
/**
* Gets the value of the name property.
*
Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/RepositoryKind.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/RepositoryKind.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/RepositoryKind.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/RepositoryKind.java Tue Dec 6 16:19:14 2011
@@ -17,6 +17,7 @@
*/
package org.apache.ambari.common.rest.entities;
+import java.util.Arrays;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
@@ -38,10 +39,45 @@ import javax.xml.bind.annotation.XmlType
public class RepositoryKind {
@XmlAttribute(required = true)
- protected String kind;
+ private String kind;
@XmlElement(required = true)
- protected List<String> urls;
+ private List<String> urls;
+
+ public RepositoryKind() {
+ // PASS
+ }
+
+ public RepositoryKind(String name, String... urls) {
+ this.kind = name;
+ this.urls = Arrays.asList(urls);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ } else if (other == null || other.getClass() != getClass()) {
+ return false;
+ } else {
+ RepositoryKind repoKind = (RepositoryKind) other;
+ if (!kind.equals(repoKind.kind) || urls.size() != repoKind.urls.size()){
+ return false;
+ } else {
+ for(int i = 0; i < urls.size(); i++) {
+ if (!urls.get(i).equals(repoKind.urls.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return kind.hashCode();
+ }
/**
* Gets the value of the urls property.
Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Role.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Role.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Role.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Role.java Tue Dec 6 16:19:14 2011
@@ -40,6 +40,15 @@ public class Role {
@XmlElement(required = true)
protected Configuration configuration;
+ public Role() {
+ // PASS
+ }
+
+ public Role(String name, Configuration conf) {
+ this.name = name;
+ this.configuration = conf;
+ }
+
/**
* Gets the value of the name property.
*
Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Stack.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Stack.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Stack.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/Stack.java Tue Dec 6 16:19:14 2011
@@ -17,9 +17,7 @@
*/
package org.apache.ambari.common.rest.entities;
-import java.io.IOException;
-import java.util.Date;
-import java.util.GregorianCalendar;
+import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
@@ -29,8 +27,6 @@ import javax.xml.bind.annotation.XmlElem
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
-import javax.xml.datatype.DatatypeConfigurationException;
-import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
@@ -124,7 +120,7 @@ public class Stack {
* The revision number of the parent stack.
*/
@XmlAttribute
- protected String parentRevision;
+ protected int parentRevision = -1;
/**
* When this revision of the stack was created.
@@ -151,8 +147,29 @@ public class Stack {
* the version of each component and the associated configuration.
*/
@XmlElement
- protected List<Component> components;
-
+ protected List<Component> components = new ArrayList<Component>();
+
+ /**
+ * Create an empty stack
+ */
+ public Stack() {
+ }
+
+ /**
+ * Do a shallow copy of the stack
+ * @param orig the source stack
+ */
+ public Stack(Stack orig) {
+ this.components = orig.components;
+ this.configuration = orig.configuration;
+ this.creationTime = orig.creationTime;
+ this.name = orig.name;
+ this.parentName = orig.parentName;
+ this.parentRevision = orig.parentRevision;
+ this.repositories = orig.repositories;
+ this.revision = orig.revision;
+ }
+
/**
* Get the name of the stack.
* @return the name
@@ -197,13 +214,13 @@ public class Stack {
/**
* @return the parentRevision
*/
- public String getParentRevision() {
+ public int getParentRevision() {
return parentRevision;
}
/**
* @param parentRevision the parentRevision to set
*/
- public void setParentRevision(String parentRevision) {
+ public void setParentRevision(int parentRevision) {
this.parentRevision = parentRevision;
}
Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/StackInformation.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/StackInformation.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/StackInformation.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/StackInformation.java Tue Dec 6 16:19:14 2011
@@ -64,7 +64,7 @@ public class StackInformation {
@XmlAttribute
protected String parentName;
@XmlAttribute
- protected String parentRevision;
+ protected int parentRevision;
@XmlElement
protected List<String> component;
@XmlAttribute
@@ -122,13 +122,13 @@ public class StackInformation {
/**
* @return the parentRevision
*/
- public String getParentRevision() {
+ public int getParentRevision() {
return parentRevision;
}
/**
* @param parentRevision the parentRevision to set
*/
- public void setParentRevision(String parentRevision) {
+ public void setParentRevision(int parentRevision) {
this.parentRevision = parentRevision;
}
Modified: incubator/ambari/trunk/controller/pom.xml
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/pom.xml?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/pom.xml (original)
+++ incubator/ambari/trunk/controller/pom.xml Tue Dec 6 16:19:14 2011
@@ -231,6 +231,22 @@
<dependencies>
<dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ <version>3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject.extensions</groupId>
+ <artifactId>guice-assistedinject</artifactId>
+ <version>3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>1.8.5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.apache.ambari</groupId>
<artifactId>ambari-client</artifactId>
<version>0.1.0-SNAPSHOT</version>
@@ -311,12 +327,6 @@
<version>1.8</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <version>1.8.5</version>
- <scope>test</scope>
- </dependency>
</dependencies>
<distributionManagement>
Added: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/ComponentModule.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/ComponentModule.java?rev=1210997&view=auto
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/ComponentModule.java (added)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/ComponentModule.java Tue Dec 6 16:19:14 2011
@@ -0,0 +1,31 @@
+/**
+ * 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.ambari.components;
+
+import org.apache.ambari.components.impl.XmlComponentPluginFactoryImpl;
+
+import com.google.inject.AbstractModule;
+
+public class ComponentModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ bind(ComponentPluginFactory.class).to(XmlComponentPluginFactoryImpl.class);
+ }
+
+}
Added: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/ComponentPluginFactory.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/ComponentPluginFactory.java?rev=1210997&view=auto
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/ComponentPluginFactory.java (added)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/ComponentPluginFactory.java Tue Dec 6 16:19:14 2011
@@ -0,0 +1,28 @@
+/**
+ * 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.ambari.components;
+
+import java.io.IOException;
+
+import org.apache.ambari.common.rest.entities.ComponentDefinition;
+
+public abstract class ComponentPluginFactory {
+
+ public abstract ComponentPlugin getPlugin(ComponentDefinition info
+ ) throws IOException;
+}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/impl/XmlComponentDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/impl/XmlComponentDefinition.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/impl/XmlComponentDefinition.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/impl/XmlComponentDefinition.java Tue Dec 6 16:19:14 2011
@@ -1,3 +1,20 @@
+/**
+ * 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.ambari.components.impl;
import java.io.IOException;
@@ -20,7 +37,7 @@ import org.apache.ambari.common.rest.age
import org.apache.ambari.common.rest.agent.Command;
import org.apache.ambari.components.ComponentPlugin;
-public class XmlComponentDefinition extends ComponentPlugin {
+class XmlComponentDefinition extends ComponentPlugin {
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "component", propOrder = {
@@ -182,14 +199,6 @@ public class XmlComponentDefinition exte
}
}
- private static String getUser(ScriptCommand cmd, String user) {
- if (cmd == null || cmd.user == null) {
- return user;
- } else {
- return cmd.user;
- }
- }
-
XmlComponentDefinition(InputStream in) throws IOException {
Unmarshaller um;
try {
@@ -248,7 +257,7 @@ public class XmlComponentDefinition exte
* @param defn the name of the definition
* @throws IOException
*/
- public XmlComponentDefinition(ComponentDefinition defn) throws IOException {
+ XmlComponentDefinition(ComponentDefinition defn) throws IOException {
this(getInputStream(defn));
}
Added: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/impl/XmlComponentPluginFactoryImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/impl/XmlComponentPluginFactoryImpl.java?rev=1210997&view=auto
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/impl/XmlComponentPluginFactoryImpl.java (added)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/components/impl/XmlComponentPluginFactoryImpl.java Tue Dec 6 16:19:14 2011
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * 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.ambari.components.impl;
+
+import java.io.IOException;
+
+import org.apache.ambari.common.rest.entities.ComponentDefinition;
+import org.apache.ambari.components.ComponentPlugin;
+import org.apache.ambari.components.ComponentPluginFactory;
+
+import com.google.inject.Inject;
+
+public class XmlComponentPluginFactoryImpl extends ComponentPluginFactory {
+
+ @Inject
+ XmlComponentPluginFactoryImpl() {
+ // PASS
+ }
+
+ @Override
+ public ComponentPlugin getPlugin(ComponentDefinition info) throws IOException {
+ return new XmlComponentDefinition(info);
+ }
+
+}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Cluster.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Cluster.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Cluster.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Cluster.java Tue Dec 6 16:19:14 2011
@@ -23,22 +23,28 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import javax.ws.rs.WebApplicationException;
+
+import org.apache.ambari.common.rest.entities.Role;
import org.apache.ambari.common.rest.entities.Stack;
import org.apache.ambari.common.rest.entities.ClusterDefinition;
import org.apache.ambari.common.rest.entities.ClusterState;
import org.apache.ambari.common.rest.entities.Component;
+import org.apache.ambari.common.rest.entities.Configuration;
import org.apache.ambari.components.ComponentPlugin;
-import org.apache.ambari.components.impl.XmlComponentDefinition;
-import org.apache.ambari.datastore.DataStoreFactory;
+import org.apache.ambari.components.ComponentPluginFactory;
import org.apache.ambari.datastore.PersistentDataStore;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+
public class Cluster {
/*
* Data Store
*/
- private PersistentDataStore dataStore = DataStoreFactory.getDataStore(DataStoreFactory.ZOOKEEPER_TYPE);
+ private final PersistentDataStore dataStore;
/*
* Latest revision of cluster definition
@@ -50,22 +56,49 @@ public class Cluster {
/*
* Map of cluster revision to cluster definition
*/
- private final Map<Integer, ClusterDefinition> clusterDefinitionRevisionsList =
- new ConcurrentHashMap<Integer, ClusterDefinition>();
- private final Map<String, ComponentPlugin> plugins =
- new HashMap<String, ComponentPlugin>();
-
- /*
- * Store cluster puppet configuration
- */
- private final Map<Integer, String> clusterConfigurationRevisionList = new HashMap<Integer, String>();
-
+ private final Map<Integer, ClusterDefinition>
+ clusterDefinitionRevisionsList =
+ new ConcurrentHashMap<Integer, ClusterDefinition>();
+ private final Map<String, ComponentInfo> components =
+ new HashMap<String, ComponentInfo>();
+ private final StackFlattener flattener;
+ private final ComponentPluginFactory componentPluginFactory;
+
+ private static class ComponentInfo {
+ final ComponentPlugin plugin;
+ final Map<String, RoleInfo> roles = new HashMap<String,RoleInfo>();
+ ComponentInfo(ComponentPlugin plugin) {
+ this.plugin = plugin;
+ }
+ }
- public Cluster (String clusterName) {
+ private static class RoleInfo {
+ Configuration conf;
+ RoleInfo(Configuration conf) {
+ this.conf = conf;
+ }
+ }
+
+ @AssistedInject
+ public Cluster (StackFlattener flattener,
+ PersistentDataStore dataStore,
+ ComponentPluginFactory plugin,
+ @Assisted String clusterName) {
+ this.flattener = flattener;
+ this.dataStore = dataStore;
+ this.componentPluginFactory = plugin;
this.clusterName = clusterName;
}
- public Cluster (ClusterDefinition c, ClusterState cs) throws Exception {
+ @AssistedInject
+ public Cluster (StackFlattener flattener,
+ PersistentDataStore dataStore,
+ ComponentPluginFactory plugin,
+ @Assisted ClusterDefinition c,
+ @Assisted ClusterState cs) throws Exception {
+ this.flattener = flattener;
+ this.dataStore = dataStore;
+ this.componentPluginFactory = plugin;
this.clusterName = c.getName();
this.updateClusterDefinition(c);
this.updateClusterState(cs);
@@ -74,7 +107,7 @@ public class Cluster {
public synchronized void init () throws Exception {
this.latestRevisionNumber = dataStore.retrieveLatestClusterRevisionNumber(clusterName);
this.latestDefinition = dataStore.retrieveClusterDefinition(clusterName, this.latestRevisionNumber);
- loadPlugins(this.latestDefinition);
+ getComponents(this.latestDefinition);
this.clusterDefinitionRevisionsList.put(this.latestRevisionNumber, this.latestDefinition);
}
@@ -114,36 +147,24 @@ public class Cluster {
this.latestDefinition = c;
// find the plugins for the current definition of the cluster
- loadPlugins(c);
+ getComponents(c);
}
- /*
- * Load plugins for the current definition of the cluster
- */
- private void loadPlugins (ClusterDefinition c) throws Exception {
-
- Stacks context = Stacks.getInstance();
- Stack bp = context.getStack(c.getStackName(),
- Integer.parseInt(c.getStackRevision()));
-
- while (bp != null) {
- for(Component comp: bp.getComponents()) {
- String name = comp.getName();
- if (!plugins.containsKey(name) && comp.getDefinition() != null) {
- plugins.put(name, new XmlComponentDefinition(comp.getDefinition()));
- }
- }
-
- // go up to the parent
- if (bp.getParentName() != null) {
- bp = context.getStack(bp.getParentName(),
- Integer.parseInt(bp.getParentRevision()));
- } else {
- bp = null;
- }
+ private void getComponents(ClusterDefinition cluster
+ ) throws NumberFormatException, WebApplicationException, IOException {
+ Stack flattened = flattener.flattenStack(cluster.getStackName(),
+ Integer.parseInt(cluster.getStackRevision()));
+ for (Component component: flattened.getComponents()) {
+ ComponentPlugin plugin =
+ componentPluginFactory.getPlugin(component.getDefinition());
+ ComponentInfo info = new ComponentInfo(plugin);
+ components.put(component.getName(), info);
+ for(Role role: component.getRoles()) {
+ info.roles.put(role.getName(), new RoleInfo(role.getConfiguration()));
}
+ }
}
-
+
/**
* @return the clusterState
*/
@@ -163,11 +184,16 @@ public class Cluster {
}
public synchronized Iterable<String> getComponents() {
- return this.plugins.keySet();
+ return components.keySet();
}
public synchronized
ComponentPlugin getComponentDefinition(String component) {
- return this.plugins.get(component);
+ return components.get(component).plugin;
+ }
+
+ public synchronized
+ Configuration getConfiguration(String component, String role) {
+ return components.get(component).roles.get(role).conf;
}
}
Added: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/ClusterFactory.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/ClusterFactory.java?rev=1210997&view=auto
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/ClusterFactory.java (added)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/ClusterFactory.java Tue Dec 6 16:19:14 2011
@@ -0,0 +1,26 @@
+/*
+ * 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.ambari.controller;
+
+import org.apache.ambari.common.rest.entities.ClusterDefinition;
+import org.apache.ambari.common.rest.entities.ClusterState;
+
+public interface ClusterFactory {
+ public Cluster create(String name);
+ public Cluster create(ClusterDefinition definition, ClusterState state);
+}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Clusters.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Clusters.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Clusters.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Clusters.java Tue Dec 6 16:19:14 2011
@@ -20,12 +20,17 @@ package org.apache.ambari.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Hashtable;
import java.util.List;
+import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
import org.apache.ambari.common.rest.entities.ClusterDefinition;
import org.apache.ambari.common.rest.entities.ClusterInformation;
@@ -37,13 +42,16 @@ import org.apache.ambari.common.rest.ent
import org.apache.ambari.common.rest.entities.Role;
import org.apache.ambari.common.rest.entities.RoleToNodes;
import org.apache.ambari.common.rest.entities.Stack;
-import org.apache.ambari.datastore.DataStoreFactory;
import org.apache.ambari.datastore.PersistentDataStore;
import org.apache.ambari.resource.statemachine.ClusterFSM;
import org.apache.ambari.resource.statemachine.StateMachineInvoker;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
public class Clusters {
// TODO: replace system.out.print by LOG
private static Log LOG = LogFactory.getLog(Clusters.class);
@@ -52,24 +60,23 @@ public class Clusters {
* Operational clusters include both active and inactive clusters
*/
protected ConcurrentHashMap<String, Cluster> operational_clusters = new ConcurrentHashMap<String, Cluster>();
- protected PersistentDataStore dataStore = DataStoreFactory.getDataStore(DataStoreFactory.ZOOKEEPER_TYPE);
+ private final PersistentDataStore dataStore;
- private static Clusters ClustersTypeRef=null;
-
- private Clusters() {
+ private final Stacks stacks;
+ private final Nodes nodes;
+ private final ClusterFactory clusterFactory;
+
+ @Inject
+ private Clusters(Stacks stacks, Nodes nodes,
+ PersistentDataStore dataStore,
+ ClusterFactory clusterFactory) throws Exception {
+ this.stacks = stacks;
+ this.nodes = nodes;
+ this.dataStore = dataStore;
+ this.clusterFactory = clusterFactory;
+ recoverClustersStateAfterRestart();
}
- public static synchronized Clusters getInstance() {
- if(ClustersTypeRef == null) {
- ClustersTypeRef = new Clusters();
- }
- return ClustersTypeRef;
- }
-
- public Object clone() throws CloneNotSupportedException {
- throw new CloneNotSupportedException();
- }
-
/*
* Wrapper method over datastore API
*/
@@ -88,7 +95,7 @@ public class Clusters {
public synchronized Cluster getClusterByName(String clusterName) throws Exception {
if (clusterExists(clusterName)) {
if (!this.operational_clusters.containsKey(clusterName)) {
- Cluster cls = new Cluster(clusterName);
+ Cluster cls = clusterFactory.create(clusterName);
cls.init();
this.operational_clusters.put(clusterName, cls);
}
@@ -109,8 +116,9 @@ public class Clusters {
/*
* Add Cluster Entry into data store and memory cache
*/
- public synchronized Cluster addClusterEntry (ClusterDefinition cdef, ClusterState cs) throws Exception {
- Cluster cls = new Cluster (cdef, cs);
+ public synchronized Cluster addClusterEntry (ClusterDefinition cdef,
+ ClusterState cs) throws Exception {
+ Cluster cls = clusterFactory.create(cdef, cs);
this.operational_clusters.put(cdef.getName(), cls);
return cls;
}
@@ -488,23 +496,16 @@ public class Clusters {
* Check if the cluster stack and its parents exist
* getStack would throw exception if it does not find the stack
*/
- Stack bp = Stacks.getInstance()
- .getStack(cdef.getStackName(), Integer.parseInt(cdef.getStackRevision()));
+ Stack bp = stacks.getStack(cdef.getStackName(), Integer.parseInt(cdef.getStackRevision()));
while (bp.getParentName() != null) {
- if (bp.getParentRevision() == null) {
- bp = Stacks.getInstance()
- .getStack(bp.getParentName(), -1);
- } else {
- bp = Stacks.getInstance()
- .getStack(bp.getParentName(), Integer.parseInt(bp.getParentRevision()));
- }
+ bp = stacks.getStack(bp.getParentName(), bp.getParentRevision());
}
/*
* Check if nodes requested for cluster are not already allocated to other clusters
*/
- ConcurrentHashMap<String, Node> all_nodes = Nodes.getInstance().getNodes();
+ ConcurrentHashMap<String, Node> all_nodes = nodes.getNodes();
List<String> cluster_node_range = new ArrayList<String>();
cluster_node_range.addAll(getHostnamesFromRangeExpressions(cdef.getNodes()));
List<String> preallocatedhosts = new ArrayList<String>();
@@ -560,7 +561,7 @@ public class Clusters {
*/
private synchronized void updateClusterNodesReservation (String clusterName, ClusterDefinition clsDef) throws Exception {
- ConcurrentHashMap<String, Node> all_nodes = Nodes.getInstance().getNodes();
+ ConcurrentHashMap<String, Node> all_nodes = nodes.getNodes();
List<String> cluster_node_range = new ArrayList<String>();
cluster_node_range.addAll(getHostnamesFromRangeExpressions(clsDef.getNodes()));
@@ -569,7 +570,7 @@ public class Clusters {
* -- throw exception, if any nodes are pre-associated with other cluster
*/
List<String> nodes_currently_allocated_to_cluster = new ArrayList<String>();
- for (Node n : Nodes.getInstance().getNodes().values()) {
+ for (Node n : nodes.getNodes().values()) {
if ( n.getNodeState().getClusterName() != null &&
n.getNodeState().getClusterName().equals(clusterName)) {
nodes_currently_allocated_to_cluster.add(n.getName());
@@ -618,8 +619,8 @@ public class Clusters {
}
} else {
Date epoch = new Date(0);
- Nodes.getInstance().checkAndUpdateNode(node_name, epoch);
- Node node = Nodes.getInstance().getNode(node_name);
+ nodes.checkAndUpdateNode(node_name, epoch);
+ Node node = nodes.getNode(node_name);
/*
* TODO: Set agentInstalled = true, unless controller uses SSH to setup the agent
*/
@@ -641,16 +642,6 @@ public class Clusters {
}
}
- /*
- * This function disassociate all the nodes from the cluster. The clsuterID associated w/
- * cluster will be reset by heart beat when node reports all clean.
- */
- private synchronized void releaseClusterNodes (String clusterName) throws Exception {
- for (Node clusterNode : Nodes.getInstance().getClusterNodes (clusterName, "", "")) {
- clusterNode.releaseNodeFromCluster();
- }
- }
-
/**
* Update Node to Roles association.
* If role is not explicitly associated w/ any node, then assign it w/ default role
@@ -674,10 +665,10 @@ public class Clusters {
for (RoleToNodes e : roleToNodesList) {
List<String> hosts = getHostnamesFromRangeExpressions(e.getNodes());
for (String host : hosts) {
- if (Nodes.getInstance().getNodes().get(host).getNodeState().getNodeRoleNames() == null) {
- Nodes.getInstance().getNodes().get(host).getNodeState().setNodeRoleNames((new ArrayList<String>()));
+ if (nodes.getNodes().get(host).getNodeState().getNodeRoleNames() == null) {
+ nodes.getNodes().get(host).getNodeState().setNodeRoleNames((new ArrayList<String>()));
}
- Nodes.getInstance().getNodes().get(host).getNodeState().getNodeRoleNames().add(e.getRoleName());
+ nodes.getNodes().get(host).getNodeState().getNodeRoleNames().add(e.getRoleName());
}
}
@@ -689,10 +680,10 @@ public class Clusters {
List<String> specified_node_range = new ArrayList<String>();
specified_node_range.addAll(getHostnamesFromRangeExpressions(clusterNodes));
for (String host : specified_node_range) {
- if (Nodes.getInstance().getNodes().get(host).getNodeState().getNodeRoleNames() == null) {
- Nodes.getInstance().getNodes().get(host).getNodeState().setNodeRoleNames((new ArrayList<String>()));
- String cid = Nodes.getInstance().getNodes().get(host).getNodeState().getClusterName();
- Nodes.getInstance().getNodes().get(host).getNodeState().getNodeRoleNames().add(getDefaultRoleName(cid));
+ if (nodes.getNodes().get(host).getNodeState().getNodeRoleNames() == null) {
+ nodes.getNodes().get(host).getNodeState().setNodeRoleNames((new ArrayList<String>()));
+ String cid = nodes.getNodes().get(host).getNodeState().getClusterName();
+ nodes.getNodes().get(host).getNodeState().getNodeRoleNames().add(getDefaultRoleName(cid));
}
}
}
@@ -712,10 +703,10 @@ public class Clusters {
Stack bp;
if (!expanded) {
- bp = Stacks.getInstance().getStack(stackName, stackRevision);
+ bp = stacks.getStack(stackName, stackRevision);
} else {
// TODO: Get the derived/expanded stack
- bp = Stacks.getInstance().getStack(stackName, stackRevision);
+ bp = stacks.getStack(stackName, stackRevision);
}
return bp;
}
@@ -814,7 +805,7 @@ public class Clusters {
* Get the list of role names associated with node
*/
public List<String> getAssociatedRoleNames(String hostname) {
- return Nodes.getInstance().getNodes().get(hostname).getNodeState().getNodeRoleNames();
+ return nodes.getNodes().get(hostname).getNodeState().getNodeRoleNames();
}
/*
@@ -823,7 +814,7 @@ public class Clusters {
* Throw exception if node is not associated to with any cluster
*/
public String getDefaultRoleName(String clusterName) throws Exception {
- Cluster c = Clusters.getInstance().getClusterByName(clusterName);
+ Cluster c = getClusterByName(clusterName);
// TODO: find the default role from the clsuter stack
return "slaves-role";
}
@@ -844,7 +835,7 @@ public class Clusters {
/*
* Restart recovery for clusters
*/
- public void recoverClustersStateAfterRestart () throws Exception {
+ private void recoverClustersStateAfterRestart () throws Exception {
for (Cluster cls : this.getClustersList("ALL")) {
ClusterDefinition cdef = cls.getClusterDefinition(-1);
this.validateClusterDefinition (cdef.getName(), cdef);
@@ -872,8 +863,7 @@ public class Clusters {
public String getInstallAndConfigureScript(String clusterName, int revision) throws Exception {
ClusterDefinition c = getClusterByName (clusterName).getClusterDefinition(revision);
// TODO: ignore if comps or roles are not present in stack.
- Stacks stacksCtx = Stacks.getInstance();
- Stack stack = stacksCtx.getStack(c.getStackName(), Integer.parseInt(c.getStackRevision()));
+ Stack stack = stacks.getStack(c.getStackName(), Integer.parseInt(c.getStackRevision()));
String config = "\n$hadoop_stack_conf = { ";
if (stack.getComponents() != null) {
for (Component comp : stack.getComponents()) {
@@ -936,4 +926,92 @@ public class Clusters {
config = config + "} \n";
return config;
}
+
+ /*
+ * Return the list of nodes associated with cluster given the role name and
+ * alive state. If rolename or alive state is not specified (i.e. "") then all
+ * the nodes associated with cluster are returned.
+ */
+ public List<Node> getClusterNodes (String clusterName, String roleName,
+ String alive) throws Exception {
+
+ List<Node> list = new ArrayList<Node>();
+ Map<String,Node> nodeMap = nodes.getNodes();
+ ClusterDefinition c = operational_clusters.get(clusterName).
+ getClusterDefinition(-1);
+ if (c.getNodes() == null || c.getNodes().equals("") ||
+ getClusterByName(clusterName).getClusterState().getState().
+ equalsIgnoreCase("ATTIC")) {
+ String msg = "No nodes are reserved for the cluster. Typically" +
+ " cluster in ATTIC state does not have any nodes reserved";
+ throw new WebApplicationException((new ExceptionResponse(msg,
+ Response.Status.NO_CONTENT)).get());
+ }
+ List<String> hosts = getHostnamesFromRangeExpressions(c.getNodes());
+ for (String host : hosts) {
+ if (!nodeMap.containsKey(host)) {
+ String msg = "Node ["+host+
+ "] is expected to be registered w/ controller but not "+
+ "locatable";
+ throw new WebApplicationException((new ExceptionResponse(msg,
+ Response.Status.INTERNAL_SERVER_ERROR)).get());
+ }
+ Node n = nodeMap.get(host);
+ if (roleName != null && !roleName.equals("")) {
+ if (!n.getNodeState().getNodeRoleNames().contains(roleName)) {
+ continue;
+ }
+ }
+
+ // Heart beat is set to epoch during node initialization.
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.setTime(new Date());
+ XMLGregorianCalendar curTime =
+ DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
+ if (alive.equals("") || (alive.equalsIgnoreCase("true") &&
+ Nodes.getTimeDiffInMillis(curTime, n.getNodeState().
+ getLastHeartbeatTime()) < Nodes.NODE_NOT_RESPONDING_DURATION)
+ || (alive.equals("false") &&
+ Nodes.getTimeDiffInMillis(curTime,
+ n.getNodeState().getLastHeartbeatTime()) >=
+ Nodes.NODE_NOT_RESPONDING_DURATION)) {
+ list.add(nodeMap.get(host));
+ }
+ }
+ return list;
+ }
+
+ /*
+ * Returns the <key="name", value="revision"> hash table for cluster
+ * referenced stacks. This would include any indirectly referenced parent
+ * stacks as well.
+ */
+ public Hashtable<String, String> getClusterReferencedStacksList()
+ throws Exception {
+ Hashtable<String, String> clusterStacks = new Hashtable<String, String>();
+ List<String> clusterNames = dataStore.retrieveClusterList();
+ for (String clsName : clusterNames) {
+ Cluster c = getClusterByName(clsName);
+ String cBPName = c.getClusterDefinition(-1).getStackName();
+ String cBPRevision = c.getClusterDefinition(-1).getStackRevision();
+ clusterStacks.put(cBPName, cBPRevision);
+ Stack bpx = stacks.getStack(cBPName, Integer.parseInt(cBPRevision));
+ while (bpx.getParentName() != null) {
+ bpx = stacks.getStack(bpx.getParentName(),
+ bpx.getParentRevision());
+ clusterStacks.put(bpx.getName(), bpx.getRevision());
+ }
+ }
+ return clusterStacks;
+ }
+
+ /**
+ * Is the given stack used in any cluster?
+ * @param stackName the stack to check on
+ * @return is the stack used
+ * @throws Exception
+ */
+ public boolean isStackUsed(String stackName) throws Exception {
+ return getClusterReferencedStacksList().containsKey(stackName);
+ }
}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Controller.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Controller.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Controller.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Controller.java Tue Dec 6 16:19:14 2011
@@ -35,26 +35,19 @@ import org.mortbay.jetty.servlet.Servlet
import org.mortbay.resource.Resource;
import org.mortbay.resource.ResourceCollection;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
import com.sun.jersey.spi.container.servlet.ServletContainer;
+@Singleton
public class Controller {
private static Log LOG = LogFactory.getLog(Controller.class);
public static int CONTROLLER_PORT = 4080;
- private static Controller instance = new Controller();
private Server server = null;
public volatile boolean running = true; // true while controller runs
- private HeartbeatHandler hbHandler;
-
- public static Controller getInstance() {
- return instance;
- }
-
- public HeartbeatHandler getHeartbeatHandler() {
- return hbHandler;
- }
public void run() {
- hbHandler = new HeartbeatHandler();
server = new Server(CONTROLLER_PORT);
try {
@@ -105,20 +98,6 @@ public class Controller {
server.setStopAtShutdown(true);
/*
- * Initialize the resources
- */
- Clusters clustersCtx = Clusters.getInstance();
- Stacks stacksCtx = Stacks.getInstance();
- Nodes nodesCtx = Nodes.getInstance();
-
- /*
- * Recover controller state before oopening up the server to clients
- * Restore stacks before clusters
- */
- stacksCtx.recoverStacksAfterRestart();
- clustersCtx.recoverClustersStateAfterRestart();
-
- /*
* Start the server after controller state is recovered.
*/
server.start();
@@ -138,9 +117,10 @@ public class Controller {
}
public static void main(String[] args) {
+ Injector injector = Guice.createInjector(new ControllerModule());
DaemonWatcher.createInstance(System.getProperty("PID"), 9100);
try {
- Controller controller = Controller.getInstance();
+ Controller controller = injector.getInstance(Controller.class);
if (controller != null) {
controller.run();
}
Added: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/ControllerModule.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/ControllerModule.java?rev=1210997&view=auto
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/ControllerModule.java (added)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/ControllerModule.java Tue Dec 6 16:19:14 2011
@@ -0,0 +1,46 @@
+/**
+ * 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.ambari.controller;
+
+import org.apache.ambari.components.ComponentModule;
+import org.apache.ambari.controller.rest.agent.ControllerResource;
+import org.apache.ambari.controller.rest.resources.ClustersResource;
+import org.apache.ambari.controller.rest.resources.NodesResource;
+import org.apache.ambari.controller.rest.resources.StacksResource;
+import org.apache.ambari.datastore.PersistentDataStore;
+import org.apache.ambari.datastore.impl.StaticDataStore;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+
+public class ControllerModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ install(new ComponentModule());
+ bind(PersistentDataStore.class).to(StaticDataStore.class);
+ requestStaticInjection(ClustersResource.class,
+ NodesResource.class,
+ StacksResource.class,
+ ControllerResource.class);
+ install(new FactoryModuleBuilder()
+ .implement(Cluster.class,Cluster.class)
+ .build(ClusterFactory.class));
+ }
+
+}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/HeartbeatHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/HeartbeatHandler.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/HeartbeatHandler.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/HeartbeatHandler.java Tue Dec 6 16:19:14 2011
@@ -46,18 +46,30 @@ import org.apache.ambari.resource.statem
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
public class HeartbeatHandler {
private Map<String, ControllerResponse> agentToHeartbeatResponseMap =
Collections.synchronizedMap(new HashMap<String, ControllerResponse>());
private static Log LOG = LogFactory.getLog(HeartbeatHandler.class);
+ private final Clusters clusters;
+ private final Nodes nodes;
+
+ @Inject
+ HeartbeatHandler(Clusters clusters, Nodes nodes) {
+ this.clusters = clusters;
+ this.nodes = nodes;
+ }
public ControllerResponse processHeartBeat(HeartBeat heartbeat)
throws Exception {
String hostname = heartbeat.getHostname();
Date heartbeatTime = new Date(System.currentTimeMillis());
- Nodes.getInstance().checkAndUpdateNode(hostname, heartbeatTime);
+ nodes.checkAndUpdateNode(hostname, heartbeatTime);
ControllerResponse response =
agentToHeartbeatResponseMap.get(heartbeat.getHostname());
@@ -84,15 +96,14 @@ public class HeartbeatHandler {
for (ClusterNameAndRev clusterIdAndRev : clustersNodeBelongsTo) {
String script =
- Clusters.getInstance().getInstallAndConfigureScript(clusterName,
+ clusters.getInstallAndConfigureScript(clusterName,
clusterRev);
//send the deploy script
getInstallAndConfigureAction(script,clusterIdAndRev, allActions);
//get the cluster object corresponding to the clusterId
- Cluster cluster = Clusters.getInstance()
- .getClusterByName(clusterName);
+ Cluster cluster = clusters.getClusterByName(clusterName);
//get the state machine reference to the cluster
ClusterFSM clusterFsm = StateMachineInvoker
.getStateMachineClusterInstance(clusterName);
@@ -242,10 +253,10 @@ public class HeartbeatHandler {
private List<ClusterNameAndRev> getClustersNodeBelongsTo(String hostname)
throws Exception {
- String clusterName = Nodes.getInstance().getNode(hostname)
+ String clusterName = nodes.getNode(hostname)
.getNodeState().getClusterName();
if (clusterName != null) {
- int clusterRev = Clusters.getInstance().
+ int clusterRev = clusters.
getClusterByName(clusterName).getLatestRevisionNumber();
List<ClusterNameAndRev> l = new ArrayList<ClusterNameAndRev>();
l.add(new ClusterNameAndRev(clusterName, clusterRev));
@@ -386,8 +397,8 @@ public class HeartbeatHandler {
private boolean nodePlayingRole(String host, String role)
throws Exception {
//TODO: iteration on every call seems avoidable ..
- List<String> nodeRoles = Nodes.getInstance()
- .getNode(host).getNodeState().getNodeRoleNames();
+ List<String> nodeRoles = nodes.getNode(host).getNodeState().
+ getNodeRoleNames();
return nodeRoles.contains(role);
}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Nodes.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Nodes.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Nodes.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Nodes.java Tue Dec 6 16:19:14 2011
@@ -20,30 +20,18 @@ package org.apache.ambari.controller;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
-import org.apache.ambari.common.rest.entities.ClusterDefinition;
import org.apache.ambari.common.rest.entities.Node;
-import org.apache.ambari.common.rest.entities.RoleToNodes;
-
+import com.google.inject.Singleton;
+@Singleton
public class Nodes {
public static final String AGENT_DEPLOYMENT_STATE_TOBE_INSTALLED = "AGENT_TOBE_INSTALLED";
@@ -58,62 +46,11 @@ public class Nodes {
// node name to Node object hashmap
protected ConcurrentHashMap<String, Node> nodes = new ConcurrentHashMap<String, Node>();
- private static Nodes NodesTypeRef=null;
-
- private Nodes() {}
-
- public static synchronized Nodes getInstance() {
- if(NodesTypeRef == null) {
- NodesTypeRef = new Nodes();
- }
- return NodesTypeRef;
- }
-
- public Object clone() throws CloneNotSupportedException {
- throw new CloneNotSupportedException();
- }
-
public ConcurrentHashMap<String, Node> getNodes () {
return nodes;
}
/*
- * Return the list of nodes associated with cluster given the role name and alive state
- * If rolename or alive state is not specified (i.e. "") then all the nodes associated
- * with cluster are returned.
- */
- public List<Node> getClusterNodes (String clusterName, String roleName, String alive) throws Exception {
-
- List<Node> list = new ArrayList<Node>();
- ClusterDefinition c = Clusters.getInstance().operational_clusters.get(clusterName).getClusterDefinition(-1);
- if (c.getNodes() == null || c.getNodes().equals("") || Clusters.getInstance().getClusterByName(clusterName).getClusterState().getState().equalsIgnoreCase("ATTIC")) {
- String msg = "No nodes are reserved for the cluster. Typically cluster in ATTIC state does not have any nodes reserved";
- throw new WebApplicationException((new ExceptionResponse(msg, Response.Status.NO_CONTENT)).get());
- }
- List<String> hosts = Clusters.getInstance().getHostnamesFromRangeExpressions(c.getNodes());
- for (String host : hosts) {
- if (!this.nodes.containsKey(host)) {
- String msg = "Node ["+host+"] is expected to be registered w/ controller but not locatable";
- throw new WebApplicationException((new ExceptionResponse(msg, Response.Status.INTERNAL_SERVER_ERROR)).get());
- }
- Node n = this.nodes.get(host);
- if (roleName != null && !roleName.equals("")) {
- if (!n.getNodeState().getNodeRoleNames().contains(roleName)) { continue; }
- }
-
- // Heart beat is set to epoch during node initialization.
- GregorianCalendar cal = new GregorianCalendar();
- cal.setTime(new Date());
- XMLGregorianCalendar curTime = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
- if (alive.equals("") || (alive.equalsIgnoreCase("true") && getTimeDiffInMillis(curTime, n.getNodeState().getLastHeartbeatTime()) < NODE_NOT_RESPONDING_DURATION)
- || (alive.equals("false") && getTimeDiffInMillis(curTime, n.getNodeState().getLastHeartbeatTime()) >= NODE_NOT_RESPONDING_DURATION)) {
- list.add(this.nodes.get(host));
- }
- }
- return list;
- }
-
- /*
* Get Nodes
* TODO: simplify logic?
*/
@@ -207,7 +144,7 @@ public class Nodes {
if (node == null) {
node = new Node(name);
- Nodes.getInstance().getNodes().put(name, node);
+ getNodes().put(name, node);
}
node.getNodeState().setLastHeartbeatTime(hearbeatTime);
}
@@ -215,8 +152,11 @@ public class Nodes {
/*
* Get time difference
*/
- public long getTimeDiffInMillis (XMLGregorianCalendar t2, XMLGregorianCalendar t1) throws Exception {
- return t2.toGregorianCalendar().getTimeInMillis() - t1.toGregorianCalendar().getTimeInMillis();
+ public static long getTimeDiffInMillis (XMLGregorianCalendar t2,
+ XMLGregorianCalendar t1
+ ) throws Exception {
+ return t2.toGregorianCalendar().getTimeInMillis() -
+ t1.toGregorianCalendar().getTimeInMillis();
}
public static void main (String args[]) {
@@ -234,7 +174,7 @@ public class Nodes {
t2g.setTime(new Date());
t2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(t2g);
- System.out.println("TIME ["+Nodes.getInstance().getTimeDiffInMillis(t2, t1)+"]");
+ System.out.println("TIME ["+Nodes.getTimeDiffInMillis(t2, t1)+"]");
System.out.println("TIME1 ["+t1.toString()+"]");
System.out.println("TIME2 ["+t2.toString()+"]");
Added: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/StackFlattener.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/StackFlattener.java?rev=1210997&view=auto
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/StackFlattener.java (added)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/StackFlattener.java Tue Dec 6 16:19:14 2011
@@ -0,0 +1,258 @@
+/*
+ * 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.ambari.controller;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.ws.rs.WebApplicationException;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+
+import org.apache.ambari.common.rest.entities.Component;
+import org.apache.ambari.common.rest.entities.ComponentDefinition;
+import org.apache.ambari.common.rest.entities.Configuration;
+import org.apache.ambari.common.rest.entities.ConfigurationCategory;
+import org.apache.ambari.common.rest.entities.Property;
+import org.apache.ambari.common.rest.entities.RepositoryKind;
+import org.apache.ambari.common.rest.entities.Role;
+import org.apache.ambari.common.rest.entities.Stack;
+import org.apache.ambari.components.ComponentModule;
+import org.apache.ambari.components.ComponentPlugin;
+import org.apache.ambari.components.ComponentPluginFactory;
+import org.apache.ambari.datastore.PersistentDataStore;
+import org.apache.ambari.datastore.impl.StaticDataStore;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+
+public class StackFlattener {
+
+ private final Stacks stacks;
+ private final ComponentPluginFactory plugins;
+
+ private List<RepositoryKind> flattenRepositories(List<Stack> stacks) {
+ Map<String, List<String>> repositories =
+ new TreeMap<String, List<String>>();
+ for(int i=stacks.size()-1; i>=0; --i) {
+ Stack stack = stacks.get(i);
+ List<RepositoryKind> kindList = stack.getPackageRepositories();
+ if (kindList != null) {
+ for(RepositoryKind kind: kindList) {
+ List<String> list = repositories.get(kind.getKind());
+ if (list == null) {
+ list = new ArrayList<String>();
+ repositories.put(kind.getKind(), list);
+ }
+ list.addAll(kind.getUrls());
+ }
+ }
+ }
+
+ // translate it into a list of repositorykinds
+ List<RepositoryKind> result = new ArrayList<RepositoryKind>();
+ for(Map.Entry<String, List<String>> item: repositories.entrySet()) {
+ RepositoryKind kind = new RepositoryKind();
+ kind.setKind(item.getKey());
+ kind.setUrls(item.getValue());
+ result.add(kind);
+ }
+ return result;
+ }
+
+ /**
+ * Build the list of stacks in the inheritance tree.
+ * The base stack is at the front of the list and the final one is last
+ * @param stackName the name of the final stack
+ * @param stackRevision the revision of the final stack
+ * @return the lists of stacks
+ * @throws IOException
+ * @throws WebApplicationException
+ */
+ private List<Stack> getStackList(String stackName,
+ int stackRevision
+ ) throws WebApplicationException,
+ IOException {
+ Stack stack = stacks.getStack(stackName, stackRevision);
+ List<Stack> result = new ArrayList<Stack>();
+ while (stack != null) {
+ result.add(0, stack);
+ String parentName = stack.getParentName();
+ int parentRev = stack.getParentRevision();
+ if (parentName != null) {
+ stack = stacks.getStack(parentName, parentRev);
+ } else {
+ stack = null;
+ }
+ }
+ return result;
+ }
+
+ private Set<String> getComponents(List<Stack> stacks) {
+ Set<String> result = new TreeSet<String>();
+ for(Stack stack: stacks) {
+ for(Component comp: stack.getComponents()) {
+ result.add(comp.getName());
+ }
+ }
+ return result;
+ }
+
+ private void mergeInConfiguration(Map<String, Map<String, Property>> map,
+ Configuration conf) {
+ if (conf != null) {
+ for (ConfigurationCategory category: conf.getCategory()) {
+ Map<String, Property> categoryMap = map.get(category.getName());
+ if (categoryMap == null) {
+ categoryMap = new TreeMap<String, Property>();
+ map.put(category.getName(), categoryMap);
+ }
+ for (Property prop: category.getProperty()) {
+ categoryMap.put(prop.getName(), prop);
+ }
+ }
+ }
+ }
+
+ private Configuration buildConfig(Map<String, Map<String, Property>> map) {
+ Configuration conf = new Configuration();
+ List<ConfigurationCategory> categories = conf.getCategory();
+ for(String categoryName: map.keySet()) {
+ ConfigurationCategory category = new ConfigurationCategory();
+ categories.add(category);
+ category.setName(categoryName);
+ List<Property> properties = category.getProperty();
+ for (Property property: map.get(categoryName).values()) {
+ properties.add(property);
+ }
+ }
+ return conf;
+ }
+
+ private Configuration buildClientConfiguration(List<Stack> stacks) {
+ Map<String, Map<String, Property>> newConfig =
+ new TreeMap<String, Map<String, Property>>();
+ for(Stack stack: stacks) {
+ mergeInConfiguration(newConfig, stack.getConfiguration());
+ }
+ return buildConfig(newConfig);
+ }
+
+ private Configuration flattenConfiguration(List<Stack> stacks,
+ String componentName,
+ String roleName) {
+ Map<String, Map<String, Property>> newConfig =
+ new TreeMap<String, Map<String,Property>>();
+ for(Stack stack: stacks) {
+ mergeInConfiguration(newConfig, stack.getConfiguration());
+ for (Component component: stack.getComponents()) {
+ if (component.getName().equals(componentName)) {
+ mergeInConfiguration(newConfig, component.getConfiguration());
+ List<Role> roleList = component.getRoles();
+ if (roleList != null) {
+ for (Role role: roleList) {
+ if (role.getName().equals(roleName)) {
+ mergeInConfiguration(newConfig, role.getConfiguration());
+ }
+ }
+ }
+ }
+ }
+ }
+ return buildConfig(newConfig);
+ }
+
+ private Component flattenComponent(String name,
+ List<Stack> stacks) throws IOException {
+ Component result = null;
+ for(Stack stack: stacks) {
+ for(Component comp: stack.getComponents()) {
+ if (comp.getName().equals(name)) {
+ if (result != null) {
+ result.mergeInto(comp);
+ } else {
+ result = new Component();
+ result.setDefinition(new ComponentDefinition());
+ result.mergeInto(comp);
+ }
+ }
+ }
+ }
+ // we don't want the component config
+ result.setConfiguration(null);
+ List<Role> roles = new ArrayList<Role>();
+ result.setRoles(roles);
+ ComponentPlugin plugin = plugins.getPlugin(result.getDefinition());
+ for(String roleName: plugin.getActiveRoles()) {
+ Role role = new Role();
+ roles.add(role);
+ role.setName(roleName);
+ role.setConfiguration(flattenConfiguration(stacks, name, roleName));
+ }
+ return result;
+ }
+
+ @Inject
+ StackFlattener(Stacks stacks, ComponentPluginFactory plugins) {
+ this.stacks = stacks;
+ this.plugins = plugins;
+ }
+
+ public Stack flattenStack(String stackName, int stackRevision
+ ) throws WebApplicationException, IOException {
+ List<Stack> stacks = getStackList(stackName, stackRevision);
+ Stack result = new Stack(stacks.get(stacks.size()-1));
+ result.setParentName(null);
+ result.setPackageRepositories(flattenRepositories(stacks));
+ List<Component> components = new ArrayList<Component>();
+ result.setComponents(components);
+ for(String componentName: getComponents(stacks)) {
+ components.add(flattenComponent(componentName, stacks));
+ }
+ result.setConfiguration(buildClientConfiguration(stacks));
+ return result;
+ }
+
+ private static class TestModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ install(new ComponentModule());
+ bind(PersistentDataStore.class).to(StaticDataStore.class);
+ }
+
+ }
+
+ public static void main(String[] args) throws Exception {
+ Injector injector = Guice.createInjector(new TestModule());
+ JAXBContext jaxbContext =
+ JAXBContext.newInstance("org.apache.ambari.common.rest.entities");
+ Marshaller marsh = jaxbContext.createMarshaller();
+ StackFlattener flatten = injector.getInstance(StackFlattener.class);
+ Stack stack = flatten.flattenStack(args[0], 0);
+ marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+ marsh.marshal(stack, System.out);
+ }
+}
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Stacks.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Stacks.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Stacks.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Stacks.java Tue Dec 6 16:19:14 2011
@@ -26,84 +26,42 @@ import java.io.Reader;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Date;
-import java.util.Hashtable;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.apache.ambari.common.rest.entities.Stack;
import org.apache.ambari.common.rest.entities.StackInformation;
import org.apache.ambari.common.rest.entities.Component;
import org.apache.ambari.common.rest.entities.Property;
-import org.apache.ambari.datastore.DataStoreFactory;
import org.apache.ambari.datastore.PersistentDataStore;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
-import org.mortbay.log.Log;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
public class Stacks {
- private static Stacks StacksRef=null;
-
- private Stacks() {
- try {
- JAXBContext jaxbContext =
- JAXBContext.newInstance("org.apache.ambari.common.rest.entities");
- if (!this.dataStore.stackExists("hadoop-security")) {
- loadDummyStack(jaxbContext, "hadoop-security", 0);
- }
- } catch (JAXBException e) {
- throw new RuntimeException("Can't create jaxb context", e);
- } catch (Exception e) {
- throw new RuntimeException("Can't create jaxb context", e);
- }
- }
-
- public void loadDummyStack (JAXBContext jaxbContext,
- String name, int revision) throws Exception {
- try {
- Unmarshaller um = jaxbContext.createUnmarshaller();
- String resourceName =
- "org/apache/ambari/stacks/" + name + "-" + revision + ".xml";
- InputStream in =
- ClassLoader.getSystemResourceAsStream(resourceName);
- Stack bp = (Stack) um.unmarshal(in);
- bp.setName(name);
- bp.setRevision(Integer.toString(revision));
- addStack(name, bp);
- } catch (IOException e) {
- Log.warn("Problem loading stack " + name + " rev " + revision,
- e);
- } catch (JAXBException e) {
- Log.warn("Problem loading stack " + name + " rev " + revision,
- e);
- }
- }
-
- public static synchronized Stacks getInstance() {
- if(StacksRef == null) {
- StacksRef = new Stacks();
- }
- return StacksRef;
- }
+ private final PersistentDataStore dataStore;
- public Object clone() throws CloneNotSupportedException {
- throw new CloneNotSupportedException();
+ @Inject
+ Stacks(PersistentDataStore dataStore) throws IOException {
+ this.dataStore = dataStore;
+ recoverStacksAfterRestart();
}
-
+
/*
* Stack name -> latest revision is always cached for each stack.
*
*/
protected ConcurrentHashMap<String, Integer> stacks = new ConcurrentHashMap<String, Integer>();
- protected PersistentDataStore dataStore = DataStoreFactory.getDataStore(DataStoreFactory.ZOOKEEPER_TYPE);
/*
@@ -125,7 +83,8 @@ public class Stacks {
/*
* Get stack. If revision = -1 then return latest revision
*/
- public Stack getStack(String stackName, int revision) throws Exception {
+ public Stack getStack(String stackName, int revision
+ ) throws WebApplicationException, IOException {
if (!stackExists(stackName)) {
String msg = "Stack ["+stackName+"] is not defined";
@@ -206,10 +165,6 @@ public class Stacks {
(stack.getParentName().equals("") || stack.getParentName().equalsIgnoreCase("null"))) {
stack.setParentName(null);
}
- if (stack.getParentRevision() == null || stack.getParentRevision().equals("") ||
- stack.getParentRevision().equalsIgnoreCase("null")) {
- stack.setParentRevision("-1");
- }
/*
* Set the creation time
*/
@@ -273,52 +228,15 @@ public class Stacks {
}
/*
- * Delete the stack including all its versions
+ * Delete the stack including all its versions.
+ * The caller must ensure that no cluster uses this stack.
*/
public void deleteStack(String stackName) throws Exception {
-
- /*
- * Check if the specified stack is used in any cluster definition
- */
- Hashtable<String, String> clusterReferencedStackList = getClusterReferencedStacksList();
- if (clusterReferencedStackList.containsKey(stackName)) {
- String msg = "One or more clusters are associated with the specified stack";
- throw new WebApplicationException((new ExceptionResponse(msg, Response.Status.NOT_ACCEPTABLE)).get());
- }
-
- /*
- * If no cluster is associated then remove the stack
- */
dataStore.deleteStack(stackName);
this.stacks.remove(stackName);
}
/*
- * Returns the <key="name", value="revision"> hash table for cluster referenced stacks
- * This would include any indirectly referenced parent stacks as well
- */
- public Hashtable<String, String> getClusterReferencedStacksList() throws Exception {
- Hashtable<String, String> clusterStacks = new Hashtable<String, String>();
- List<String> clusterNames = dataStore.retrieveClusterList();
- for (String clsName : clusterNames) {
- Cluster c = Clusters.getInstance().getClusterByName(clsName);
- String cBPName = c.getClusterDefinition(-1).getStackName();
- String cBPRevision = c.getClusterDefinition(-1).getStackRevision();
- clusterStacks.put(cBPName, cBPRevision);
- Stack bpx = this.getStack(cBPName, Integer.parseInt(cBPRevision));
- while (bpx.getParentName() != null) {
- if (bpx.getParentRevision() == null) {
- bpx = this.getStack(bpx.getParentName(), -1);
- } else {
- bpx = this.getStack(bpx.getParentName(), Integer.parseInt(bpx.getParentRevision()));
- }
- clusterStacks.put(bpx.getName(), bpx.getRevision());
- }
- }
- return clusterStacks;
- }
-
- /*
* UTIL methods
*/
public Property getProperty(String key, String value) {
@@ -349,7 +267,7 @@ public class Stacks {
}
}
- public void recoverStacksAfterRestart() throws IOException {
+ private void recoverStacksAfterRestart() throws IOException {
List<String> stackList = dataStore.retrieveStackList();
for (String stackName : stackList) {
this.stacks.put(stackName, dataStore.retrieveLatestStackRevisionNumber(stackName));
Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/agent/ControllerResource.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/agent/ControllerResource.java?rev=1210997&r1=1210996&r2=1210997&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/agent/ControllerResource.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/agent/ControllerResource.java Tue Dec 6 16:19:14 2011
@@ -49,6 +49,8 @@ import org.apache.ambari.controller.Hear
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import com.google.inject.Inject;
+
/**
* Controller Resource represents Ambari controller.
* It provides API for Ambari agents to get the cluster configuration changes
@@ -57,8 +59,14 @@ import org.apache.commons.logging.LogFac
*/
@Path("controller")
public class ControllerResource {
- private HeartbeatHandler hh = new HeartbeatHandler();
+ private static HeartbeatHandler hh;
private static Log LOG = LogFactory.getLog(ControllerResource.class);
+
+ @Inject
+ static void setHandler(HeartbeatHandler handler) {
+ hh = handler;
+ }
+
/**
* Update state of the node (Internal API to be used by Ambari agent).
*