/*
* � Copyright IBM Corp. 2015
*
* Licensed 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 com.ibm.xsp.extlib.designer.bluemix.manifest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.Yaml;
import com.ibm.commons.util.StringUtil;
import com.ibm.xsp.extlib.designer.bluemix.BluemixLogger;
import com.ibm.xsp.extlib.designer.bluemix.config.BluemixConfig;
import com.ibm.xsp.extlib.designer.bluemix.util.BluemixUtil;
/**
* @author Gary Marjoram
*
*/
public class ManifestUtil {
private final static String _MANIFEST_FILENAME = "manifest.yml"; // $NON-NLS-1$
public static void writeDefaultManifest(BluemixConfig config, String dbName, LinkedHashMap<String, String> extraEnv) {
// Create the manifest objects
Map<Object, Object> manifest = new LinkedHashMap<Object, Object>();
List<Map<Object, Object>> applications = new ArrayList<Map<Object, Object>>();
Map<Object, Object> application = new LinkedHashMap<Object, Object>();
// Build up the application map
application.put(ManifestAppProps.NAME_TAG, config.appName);
application.put(ManifestAppProps.HOST_TAG, config.host);
application.put(ManifestAppProps.INSTANCES_TAG, new Integer(1));
application.put(ManifestAppProps.MEMORY_TAG, "512M"); // $NON-NLS-1$
application.put(ManifestAppProps.TIMEOUT_TAG, new Integer(180));
application.put(ManifestAppProps.BUILD_PACK_TAG, "xpages_buildpack"); // $NON-NLS-1$
application.put(ManifestAppProps.COMMAND_TAG, "/app/launch_xpages_webcontainer"); // $NON-NLS-1$
// Environment Vars
LinkedHashMap<String, String> envMap = new LinkedHashMap<String, String>();
envMap.put("APP_HOME_URL", "/" + BluemixUtil.getNsfName(dbName)); // $NON-NLS-1$
envMap.put("APP_PRELOAD_DB", BluemixUtil.getNsfName(dbName)); // $NON-NLS-1$
if (extraEnv != null) {
envMap.putAll(extraEnv);
}
application.put(ManifestAppProps.ENV_TAG, envMap);
// Add application
applications.add(application);
manifest.put(BluemixManifest.APPLICATIONS_TAG, applications);
// Dump the yaml to a String
DumperOptions options = new DumperOptions();
options.setExplicitStart(true);
options.setCanonical(false);
options.setPrettyFlow(true);
options.setDefaultFlowStyle(FlowStyle.BLOCK);
Yaml yaml = new Yaml(options);
String manifestString = yaml.dump(manifest);
// Write the yaml String to the file
OutputStream os = null;
try {
File file = getManifestFile(config);
os = new FileOutputStream(file);
os.write(manifestString.getBytes(ResourcesPlugin.getEncoding()));
} catch (Exception e) {
if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) {
BluemixLogger.BLUEMIX_LOGGER.errorp(ManifestUtil.class, "writeDefaultManifest", e, "Failed to write Manifest"); // $NON-NLS-1$ $NLE-ManifestUtil.FailedtowriteManifest-2$
}
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) {
BluemixLogger.BLUEMIX_LOGGER.errorp(ManifestUtil.class, "writeDefaultManifest", e, "Failed to close os"); // $NON-NLS-1$ $NLE-ManifestUtil.Failedtocloseos-2$
}
}
}
}
}
public static File getManifestFile(BluemixConfig config) {
return getManifestFile(config.directory);
}
public static File getManifestFile(String directory) {
IPath path = new Path(directory).addTrailingSeparator().append(_MANIFEST_FILENAME);
return new File(path.toOSString());
}
@SuppressWarnings("unchecked") // $NON-NLS-1$
public static Map<Object, Object> loadManifest(File manifestFile) {
Map<Object, Object> results = null;
if (manifestFile.exists() && manifestFile.isFile()) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(manifestFile);
Yaml yaml = new Yaml();
results = (Map<Object, Object>) yaml.load(inputStream);
} catch (Exception e) {
if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) {
BluemixLogger.BLUEMIX_LOGGER.errorp(ManifestUtil.class, "loadManifest", e, "Failed to load yaml file"); // $NON-NLS-1$ $NLE-ManifestUtil.Failedtoloadyamlfile-2$
}
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) {
BluemixLogger.BLUEMIX_LOGGER.errorp(ManifestUtil.class, "loadManifest", e, "Failed to close inputStream"); // $NON-NLS-1$ $NLE-ManifestUtil.FailedtocloseinputStream-2$
}
}
}
}
}
return results != null ? results : new LinkedHashMap<Object, Object>();
}
@SuppressWarnings("unchecked") // $NON-NLS-1$
public static Map<Object, Object> loadManifest(String contents) {
Map<Object, Object> results = null;
try {
Yaml yaml = new Yaml();
results = (Map<Object, Object>) yaml.load(contents);
} catch (Exception e) {
if (BluemixLogger.BLUEMIX_LOGGER.isErrorEnabled()) {
BluemixLogger.BLUEMIX_LOGGER.errorp(ManifestUtil.class, "loadManifest", e, "Failed to load yaml file from String"); // $NON-NLS-1$ $NLE-ManifestUtil.FailedtoloadyamlfilefromString-2$
}
}
return results != null ? results : new LinkedHashMap<Object, Object>();
}
// Given a yaml map - returns the String representation
public static String getContents(Map<Object, Object> rawMap) {
DumperOptions options = new DumperOptions();
options.setExplicitStart(true);
options.setCanonical(false);
options.setPrettyFlow(true);
options.setDefaultFlowStyle(FlowStyle.BLOCK);
Yaml yaml = new Yaml(options);
return (yaml.dump(rawMap));
}
public static boolean doesManifestExist(BluemixConfig config) {
File file = getManifestFile(config);
if (file.exists() && file.isFile()) {
return true;
}
return false;
}
protected static String getStringValue(Map<?, ?> containingMap, String propertyName) {
Object valObj = containingMap.get(propertyName);
if (valObj instanceof String) {
return (String) valObj;
}
return null;
}
protected static Integer getIntegerValue(Map<?, ?> containingMap, String propertyName) {
Object valObj = containingMap.get(propertyName);
if (valObj instanceof Integer) {
return (Integer) valObj;
}
return null;
}
protected static Boolean getBooleanValue(Map<?, ?> containingMap, String propertyName) {
Object valObj = containingMap.get(propertyName);
if (valObj instanceof Boolean) {
return (Boolean) valObj;
}
return null;
}
protected static Map<String, Object> getMapValueAsStrings(Map<?, ?> containingMap, String propertyName) {
Object valObj = containingMap.get(propertyName);
if (valObj instanceof Map<?, ?>) {
// Convert everything to Strings
Map<String, Object> newMap = new LinkedHashMap<String, Object>();
for (Map.Entry<?, ?> entry : ((Map<?, ?>) valObj).entrySet()) {
if (entry.getValue() != null) {
newMap.put(entry.getKey().toString(), entry.getValue().toString());
} else {
newMap.put(entry.getKey().toString(), "");
}
}
return newMap;
}
return null;
}
protected static List<?> getListValue(Map<?, ?> containingMap, String propertyName) {
Object valObj = containingMap.get(propertyName);
if (valObj instanceof List<?>) {
return (List<?>) valObj;
}
return null;
}
protected static Integer getMemoryValue( Map<?, ?> containingMap, String propertyName, String megTag, String gigTag) {
Integer mem = ManifestUtil.getIntegerValue(containingMap, propertyName);
if (mem == null) {
String memStr = ManifestUtil.getStringValue(containingMap, propertyName);
if (StringUtil.isNotEmpty(memStr)) {
memStr = memStr.trim().toUpperCase();
try {
if (memStr.endsWith(megTag)) {
mem = Integer.parseInt(memStr.substring(0, memStr.length() - megTag.length()));
}
else if (memStr.endsWith(gigTag)) {
mem = Integer.parseInt(memStr.substring(0, memStr.length() - gigTag.length())) * 1024;
}
} catch (Exception e) {
// Ignore - null will be returned
}
}
}
return mem;
}
protected static String getCommandValue(Map<?, ?> containingMap, String propertyName) {
Object valObj = containingMap.get(propertyName);
if (valObj instanceof String) {
return (String) valObj;
}
// Manifest can contain a blank command
if (containingMap.containsKey(propertyName)) {
return "";
}
return null;
}
protected static void setStringValue(Map<String, Object> containingMap, String key, String value, boolean allowEmpty) {
if ((value != null) && (allowEmpty || StringUtil.isNotEmpty(value))) {
containingMap.put(key, value);
} else {
containingMap.remove(key);
}
}
protected static void setIntegerValue(Map<String, Object> containingMap, String key, Integer value) {
if (value != null && value > 0) {
containingMap.put(key, value);
} else {
containingMap.remove(key);
}
}
protected static void setMemoryValue(Map<String, Object> containingMap, String key, Integer value, String megTag, String gigTag) {
if (value != null && value > 0) {
if ((gigTag != null) && (value % 1024 == 0)) {
containingMap.put(key, value/1024 + gigTag);
} else {
containingMap.put(key, value + megTag);
}
} else {
containingMap.remove(key);
}
}
protected static void setBooleanValue(Map<String, Object> containingMap, String key, Boolean value) {
if (value != null) {
containingMap.put(key, value);
} else {
containingMap.remove(key);
}
}
protected static void setMapValue(Map<String, Object> containingMap, String key, Map<?, ?> value) {
if (value != null) {
containingMap.put(key, value);
} else {
containingMap.remove(key);
}
}
protected static void setListValue(Map<String, Object> containingMap, String key, List<?> value) {
if (value != null) {
containingMap.put(key, value);
} else {
containingMap.remove(key);
}
}
protected static Boolean getZeroOneBooleanValue(Map<?, ?> containingMap, String propertyName) {
Object valObj = containingMap.get(propertyName);
if (valObj instanceof Integer) {
return ((Integer) valObj) == 1;
} else if (valObj instanceof String) {
return ((String) valObj).equals("1");
}
return null;
}
protected static void setZeroOneBooleanValue(Map<String, Object> containingMap, String key, Boolean value) {
if (value != null) {
if (value) {
containingMap.put(key, "1");
} else {
containingMap.put(key, "0");
}
} else {
containingMap.remove(key);
}
}
public static LinkedHashMap<String, String> convertToStringMap(Map<String, Object> map) {
LinkedHashMap<String, String> newMap = null;
if (map != null) {
newMap = new LinkedHashMap<String, String>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getValue() != null) {
newMap.put(entry.getKey(), entry.getValue().toString());
} else {
newMap.put(entry.getKey(), "");
}
}
}
return newMap;
}
}