You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sr...@apache.org on 2015/03/20 22:55:28 UTC
ambari git commit: AMBARI-10164. Provide /artifacts/theme endpoint
for each stack-version service (mpapyrkovskyy via srimanth)
Repository: ambari
Updated Branches:
refs/heads/trunk 6655d9886 -> e514c9be3
AMBARI-10164. Provide /artifacts/theme endpoint for each stack-version service (mpapyrkovskyy via srimanth)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e514c9be
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e514c9be
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e514c9be
Branch: refs/heads/trunk
Commit: e514c9be38dba024fc098bd12d92d074ce4dedad
Parents: 6655d98
Author: Srimanth Gunturi <sg...@hortonworks.com>
Authored: Fri Mar 20 14:54:31 2015 -0700
Committer: Srimanth Gunturi <sg...@hortonworks.com>
Committed: Fri Mar 20 14:54:31 2015 -0700
----------------------------------------------------------------------
.../server/api/services/AmbariMetaInfo.java | 5 +
.../internal/StackArtifactResourceProvider.java | 65 ++++++++
.../ambari/server/stack/ServiceDirectory.java | 18 +++
.../ambari/server/stack/ServiceModule.java | 32 +++-
.../apache/ambari/server/stack/ThemeModule.java | 156 +++++++++++++++++++
.../apache/ambari/server/stack/Validable.java | 4 +-
.../apache/ambari/server/state/ServiceInfo.java | 21 ++-
.../apache/ambari/server/state/ThemeInfo.java | 45 ++++++
.../ambari/server/stack/ThemeModuleTest.java | 88 +++++++++++
9 files changed, 429 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e514c9be/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index aa239ec..982f10f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -101,6 +101,11 @@ public class AmbariMetaInfo {
public static final String KERBEROS_DESCRIPTOR_FILE_NAME = "kerberos.json";
/**
+ * Filename for theme file at service layer
+ */
+ public static final String SERVICE_THEME_FILE_NAME = "theme.json";
+
+ /**
* This string is used in placeholder in places that are common for
* all operating systems or in situations where os type is not important.
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/e514c9be/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackArtifactResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackArtifactResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackArtifactResourceProvider.java
index 5b5b46f..8a6e38d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackArtifactResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackArtifactResourceProvider.java
@@ -35,6 +35,7 @@ import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.ThemeInfo;
import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory;
import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor;
@@ -46,6 +47,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -111,6 +113,11 @@ public class StackArtifactResourceProvider extends AbstractControllerResourcePro
*/
public static final String KERBEROS_DESCRIPTOR_NAME = "kerberos_descriptor";
+ /**
+ * Name of theme artifact
+ */
+ public static final String THEME_ARTIFACT_NAME = "theme";
+
/**
* KerberosDescriptorFactory used to create KerberosDescriptor instances
@@ -164,6 +171,7 @@ public class StackArtifactResourceProvider extends AbstractControllerResourcePro
Set<Resource> resources = new HashSet<Resource>();
resources.addAll(getKerberosDescriptors(request, predicate));
+ resources.addAll(getThemes(request, predicate));
// add other artifacts types here
if (resources.isEmpty()) {
@@ -263,6 +271,63 @@ public class StackArtifactResourceProvider extends AbstractControllerResourcePro
return resources;
}
+ private Set<Resource> getThemes(Request request, Predicate predicate) throws NoSuchParentResourceException,
+ NoSuchResourceException, UnsupportedPropertyException, SystemException {
+
+ Set<Resource> resources = new HashSet<Resource>();
+ for (Map<String, Object> properties : getPropertyMaps(predicate)) {
+ String artifactName = (String) properties.get(ARTIFACT_NAME_PROPERTY_ID);
+ if (artifactName == null || artifactName.equals(THEME_ARTIFACT_NAME)) {
+ String stackName = (String) properties.get(STACK_NAME_PROPERTY_ID);
+ String stackVersion = (String) properties.get(STACK_VERSION_PROPERTY_ID);
+ String stackService = (String) properties.get(STACK_SERVICE_NAME_PROPERTY_ID);
+
+ StackInfo stackInfo;
+ try {
+ stackInfo = getManagementController().getAmbariMetaInfo().getStack(stackName, stackVersion);
+ } catch (AmbariException e) {
+ throw new NoSuchParentResourceException(String.format(
+ "Parent stack resource doesn't exist: stackName='%s', stackVersion='%s'", stackName, stackVersion));
+ }
+
+ List<ServiceInfo> serviceInfoList = new ArrayList<ServiceInfo>();
+
+ if (stackService == null) {
+ serviceInfoList.addAll(stackInfo.getServices());
+ } else {
+ ServiceInfo service = stackInfo.getService(stackService);
+ if (service == null) {
+ throw new NoSuchParentResourceException(String.format(
+ "Parent stack/service resource doesn't exist: stackName='%s', stackVersion='%s', serviceName='%s'",
+ stackName, stackVersion, stackService));
+ }
+ serviceInfoList.add(service);
+ }
+
+ for (ServiceInfo serviceInfo : serviceInfoList) {
+ ThemeInfo themeInfo = serviceInfo.getThemeInfo();
+ LOG.info("Theme for stackName={}, stackVersion={}, serviceName={}, themeInfo={}", stackName, stackVersion, stackService, themeInfo);
+ if (themeInfo != null) {
+ Map<String, Object> themeMap = serviceInfo.getThemeInfo().getThemeMap();
+ if (themeMap != null) {
+ Resource resource = new ResourceImpl(Resource.Type.StackArtifact);
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+ setResourceProperty(resource, ARTIFACT_NAME_PROPERTY_ID, THEME_ARTIFACT_NAME, requestedIds);
+ setResourceProperty(resource, ARTIFACT_DATA_PROPERTY_ID, themeMap, requestedIds);
+ setResourceProperty(resource, STACK_NAME_PROPERTY_ID, stackName, requestedIds);
+ setResourceProperty(resource, STACK_VERSION_PROPERTY_ID, stackVersion, requestedIds);
+ setResourceProperty(resource, STACK_SERVICE_NAME_PROPERTY_ID, serviceInfo.getName(), requestedIds);
+
+ resources.add(resource);
+ }
+ }
+
+ }
+ }
+ }
+ return resources;
+ }
+
/**
* Get a kerberos descriptor.
*
http://git-wip-us.apache.org/repos/asf/ambari/blob/e514c9be/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
index 9b32a97..7f2ff68 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
@@ -42,6 +42,11 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
private File alertsFile;
/**
+ * theme file
+ */
+ private File themeFile;
+
+ /**
* kerberos descriptor file
*/
private File kerberosDescriptorFile;
@@ -103,6 +108,10 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
File kdf = new File(directory.getAbsolutePath()
+ File.separator + AmbariMetaInfo.KERBEROS_DESCRIPTOR_FILE_NAME);
kerberosDescriptorFile = kdf.exists() ? kdf : null;
+
+ File themeFile = new File(directory.getAbsolutePath() + File.separator + AmbariMetaInfo.SERVICE_THEME_FILE_NAME);
+ this.themeFile = themeFile.exists() ? themeFile : null;
+
}
/**
@@ -133,6 +142,14 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
}
/**
+ * Obtain theme file
+ * @return theme file
+ */
+ public File getThemeFile() {
+ return themeFile;
+ }
+
+ /**
* Obtain the Kerberos Descriptor file.
*
* @return Kerberos Descriptor file
@@ -178,4 +195,5 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
metaInfoXml.setSchemaVersion(getAbsolutePath().replace(f.getParentFile().getParentFile().getParent()+File.separator, ""));
}
}
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/e514c9be/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
index 8b94101..ab1ede5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
@@ -61,6 +61,11 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> implem
new HashMap<String, ComponentModule>();
/**
+ * Map of themes, single value currently
+ */
+ private Map<String, ThemeModule> themeModules = new HashMap<String, ThemeModule>();
+
+ /**
* Encapsulates IO operations on service directory
*/
private ServiceDirectory serviceDirectory;
@@ -73,8 +78,8 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> implem
/**
* validity flag
*/
- protected boolean valid = true;
-
+ protected boolean valid = true;
+
/**
* Constructor.
*
@@ -109,6 +114,7 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> implem
populateComponentModules();
populateConfigurationModules();
+ populateThemeModules();
}
@Override
@@ -168,6 +174,7 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> implem
mergeConfigDependencies(parent);
mergeComponents(parentModule, allStacks, commonServices);
mergeConfigurations(parentModule, allStacks, commonServices);
+ mergeThemes(parentModule, allStacks, commonServices);
mergeExcludedConfigTypes(parent);
}
@@ -273,6 +280,27 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> implem
}
}
+ private void populateThemeModules() {
+
+ ThemeModule themeModule = new ThemeModule(serviceDirectory.getThemeFile());
+
+ if (themeModule.isValid()) {
+ serviceInfo.setThemeInfo(themeModule.getModuleInfo());
+ themeModules.put(themeModule.getId(), themeModule);
+ }
+
+ //lets not fail if theme contain errors
+ }
+
+ /**
+ * Merge theme modules.
+ */
+ private void mergeThemes(ServiceModule parent, Map<String, StackModule> allStacks,
+ Map<String, ServiceModule> commonServices) throws AmbariException {
+ mergeChildModules(allStacks, commonServices, themeModules, parent.themeModules);
+
+ }
+
/**
* Merge excluded configs types with parent. Child values override parent values.
*
http://git-wip-us.apache.org/repos/asf/ambari/blob/e514c9be/ambari-server/src/main/java/org/apache/ambari/server/stack/ThemeModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ThemeModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ThemeModule.java
new file mode 100644
index 0000000..8430ad4
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ThemeModule.java
@@ -0,0 +1,156 @@
+/**
+ * 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.server.stack;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.state.ThemeInfo;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class ThemeModule extends BaseModule<ThemeModule, ThemeInfo> implements Validable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ThemeModule.class);
+ private static final ObjectMapper mapper = new ObjectMapper();
+
+ static {
+ }
+
+
+ private ThemeInfo moduleInfo = new ThemeInfo();
+ private boolean valid = true;
+ private Set<String> errors = new HashSet<String>();
+
+ public ThemeModule(File themeFile) {
+
+ if (themeFile == null) {
+ } else {
+ FileReader reader = null;
+ try {
+ reader = new FileReader(themeFile);
+ } catch (FileNotFoundException e) {
+ LOG.error("Theme file not found");
+ }
+ try {
+ TypeReference<HashMap<String,Object>> typeRef = new TypeReference<HashMap<String,Object>>() {};
+ Map<String, Object> map = mapper.readValue(reader, typeRef);
+ moduleInfo.setThemeMap(map);
+ LOG.info("Loaded theme: {}", moduleInfo);
+ } catch (IOException e) {
+ LOG.error("Unable to parse theme file ", e);
+ setValid(false);
+ setErrors("Unable to parse theme file " + themeFile);
+ }
+ }
+ }
+
+ public ThemeModule(ThemeInfo moduleInfo) {
+ this.moduleInfo = moduleInfo;
+ }
+
+ @Override
+ public void resolve(ThemeModule parent, Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) throws AmbariException {
+ if (parent.getModuleInfo() != null) {
+ moduleInfo.setThemeMap(mergedMap(parent.getModuleInfo().getThemeMap(), moduleInfo.getThemeMap()));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private Map<String, Object> mergedMap(Map<String, Object> parent, Map<String, Object> child) {
+ Map<String, Object> mergedMap = new HashMap<String, Object>();
+ if (parent == null) {
+ mergedMap = child;
+ }else if (child == null) {
+ mergedMap.putAll(parent);
+ } else {
+ mergedMap.putAll(parent);
+ for (Map.Entry<String, Object> entry : child.entrySet()) {
+ String key = entry.getKey();
+ Object childValue = entry.getValue();
+ if (childValue == null) {
+ mergedMap.remove(key);
+ }else if (!mergedMap.containsKey(key) || !(childValue instanceof Map)) {
+ //insert if absent, override if explicitly null, override primitives and arrays
+ mergedMap.put(key, childValue);
+ }else {
+ Object parentValue = mergedMap.get(key);
+ if (!(parentValue instanceof Map)) {
+ //override on type mismatch also
+ mergedMap.put(key, childValue);
+ } else {
+ mergedMap.put(key, mergedMap((Map<String, Object>)parentValue, (Map<String, Object>)childValue));
+ }
+ }
+ }
+
+ }
+
+ return mergedMap;
+ }
+
+ @Override
+ public ThemeInfo getModuleInfo() {
+ return moduleInfo;
+ }
+
+ @Override
+ public boolean isDeleted() {
+ return false;
+ }
+
+ @Override
+ public String getId() {
+ return "theme";
+ }
+
+ @Override
+ public boolean isValid() {
+ return valid;
+ }
+
+ @Override
+ public void setValid(boolean valid) {
+ this.valid = valid;
+ }
+
+ @Override
+ public void setErrors(String error) {
+ errors.add(error);
+ }
+
+ @Override
+ public void setErrors(Collection<String> error) {
+ errors.addAll(error);
+ }
+
+ @Override
+ public Collection<String> getErrors() {
+ return errors;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/e514c9be/ambari-server/src/main/java/org/apache/ambari/server/stack/Validable.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/Validable.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/Validable.java
index e8b5f24..6b75eda 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/Validable.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/Validable.java
@@ -40,9 +40,9 @@ public interface Validable {
public void setErrors(String error);
- public void setErrors(Collection error);
+ public void setErrors(Collection<String> error);
- public Collection getErrors();
+ public Collection<String> getErrors();
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/e514c9be/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
index b1ee121..939a496 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
@@ -99,7 +99,10 @@ public class ServiceInfo implements Validable{
public void setRestartRequiredAfterChange(Boolean restartRequiredAfterChange) {
this.restartRequiredAfterChange = restartRequiredAfterChange;
- }
+ }
+
+ @XmlTransient
+ private ThemeInfo themeInfo = null;
@XmlTransient
private File metricsFile = null;
@@ -604,6 +607,20 @@ public class ServiceInfo implements Validable{
return excludedConfigTypes;
}
+ /**
+ * @return theme description map
+ */
+ public ThemeInfo getThemeInfo() {
+ return themeInfo;
+ }
+
+ /**
+ * @param themeInfo map with theme description
+ */
+ public void setThemeInfo(ThemeInfo themeInfo) {
+ this.themeInfo = themeInfo;
+ }
+
public void setExcludedConfigTypes(Set<String> excludedConfigTypes) {
this.excludedConfigTypes = excludedConfigTypes;
}
@@ -627,4 +644,6 @@ public class ServiceInfo implements Validable{
}
return result;
}
+
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/e514c9be/ambari-server/src/main/java/org/apache/ambari/server/state/ThemeInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ThemeInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ThemeInfo.java
new file mode 100644
index 0000000..4f791a9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ThemeInfo.java
@@ -0,0 +1,45 @@
+/**
+ * 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.server.state;
+
+import java.util.Map;
+
+/**
+ * Wrapper for theme description
+ */
+public class ThemeInfo {
+ private Map<String, Object> themeMap = null;
+
+ public ThemeInfo() {
+ }
+
+ public Map<String, Object> getThemeMap() {
+ return themeMap;
+ }
+
+ public void setThemeMap(Map<String, Object> themeMap) {
+ this.themeMap = themeMap;
+ }
+
+ @Override
+ public String toString() {
+ return "ThemeInfo{" +
+ "themeMap=" + themeMap +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/e514c9be/ambari-server/src/test/java/org/apache/ambari/server/stack/ThemeModuleTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/ThemeModuleTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/ThemeModuleTest.java
new file mode 100644
index 0000000..500ccb3
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/ThemeModuleTest.java
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.stack;
+
+import org.apache.ambari.server.state.ThemeInfo;
+import org.apache.commons.lang.StringUtils;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+public class ThemeModuleTest {
+ private String parentTheme = "{\n" +
+ " \"Theme\": {\n" +
+ " \"name\": \"default\",\n" +
+ " \"description\": \"Default theme for HDFS service\",\n" +
+ " \"subObject\": {\n" +
+ " \"primitiveInt\" : 10,\n" +
+ " \"primitiveStr\" : \"str\",\n" +
+ " \"array1\" : [1,2,3],\n" +
+ " \"array2\" : [1,2,3]\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+ private String childTheme = "{\n" +
+ " \"Theme\": {\n" +
+ " \"description\": \"inherited theme\",\n" +
+ " \"subObject\": {\n" +
+ " \"primitiveInt\" : 12,\n" +
+ " \"primitiveStr\" : \"newStr\",\n" +
+ " \"array1\" : [1,2,3,4,5],\n" +
+ " \"array2\" : null,\n" +
+ " \"subObject2\" : {\"1\":\"1\"}\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+
+ private ObjectMapper mapper = new ObjectMapper();
+ TypeReference<HashMap<String,Object>> typeRef = new TypeReference<HashMap<String,Object>>() {};
+
+
+ @Test
+ public void testResolve() throws Exception {
+
+ ThemeInfo parentInfo = new ThemeInfo();
+ parentInfo.setThemeMap(mapper.<Map<String, Object>>readValue(parentTheme, typeRef));
+ ThemeModule parentModule = new ThemeModule(parentInfo);
+
+ ThemeInfo childInfo = new ThemeInfo();
+ childInfo.setThemeMap(mapper.<Map<String, Object>>readValue(childTheme, typeRef));
+ ThemeModule childModule = new ThemeModule(childInfo);
+
+ childModule.resolve(parentModule, null, null);
+
+ Map descriptionMap = ((Map) childInfo.getThemeMap().get("Theme"));
+ Map subObjectMap = (Map) descriptionMap.get("subObject");
+
+ assertTrue(StringUtils.equals((String) descriptionMap.get("description"), "inherited theme"));
+ assertTrue(descriptionMap.containsKey("name"));
+ assertFalse(subObjectMap.containsKey("array2"));
+ assertEquals(subObjectMap.get("primitiveInt"), 12);
+ assertEquals(subObjectMap.get("primitiveStr"), "newStr");
+ assertEquals(((List)subObjectMap.get("array1")).size(), 5);
+
+
+ }
+}
\ No newline at end of file