/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package se.kth.karamel.common.cookbookmeta; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.log4j.Logger; import se.kth.karamel.common.clusterdef.Cookbook; import se.kth.karamel.common.util.Settings; import se.kth.karamel.common.exception.CookbookUrlException; import se.kth.karamel.common.util.StringUtils; /** * * @author kamal */ public class Berksfile { private static final Logger logger = Logger.getLogger(Berksfile.class); private final List<String> fileLines; private final Map<String, Cookbook> deps = new HashMap<>(); public static Pattern LINE_PATTERN = Pattern.compile( "^cookbook\\s*(\\'[^,^'^\\\"]+\\'|\\\"[^,^'^\\\"]+\\\")\\s*," + "\\s*github\\s*:\\s*(\\'[^,^'^\\\"]+\\'|\\\"[^,^'^\\\"]+\\\")\\s*" + "(,\\s*(branch|tag|version)\\s*:\\s*(\\'[^,^'^\\\"]+\\'|\\\"[^,^'^\\\"]+\\\")\\s*)?$"); public static Set<String> validUrls = new HashSet<>(); public Berksfile(String content) throws CookbookUrlException { this.fileLines = StringUtils.toLines(content); loadDependencies(); validateGithubUrls(); } public Map<String, Cookbook> getDeps() { return deps; } private void loadDependencies() { for (String line : fileLines) { String cbName = null; String cbUrl = null; String branch = null; Matcher matcher = LINE_PATTERN.matcher(line); if (matcher.matches()) { cbName = matcher.group(1); cbName = cbName.replaceAll("'|\"", ""); cbUrl = matcher.group(2); cbUrl = cbUrl.replaceAll("'|\"", ""); if (matcher.group(3) != null) { branch = matcher.group(5); branch = branch.replaceAll("'|\"", ""); } else { branch = Settings.GITHUB_DEFAULT_BRANCH; } Cookbook cb = new Cookbook(); cb.setGithub(cbUrl); cb.setBranch(branch); deps.put(cbName, cb); } } } private void validateGithubUrls() throws CookbookUrlException { if (Settings.CB_CLASSPATH_MODE) { logger.debug("Skip cookbook dependency check in the classpath mode"); return; } for (Map.Entry<String, Cookbook> entry : deps.entrySet()) { String name = entry.getKey(); Cookbook cb = entry.getValue(); String homeUrl = cb.getUrls().cookbookUrl; String errorMsg = String.format("Cookbook-dependency '%s' doesn't refer to a valid url in Berksfile", name); try { if (validUrls.contains(homeUrl)) { logger.debug(String.format("Skip validating url '%s' since it was already validated", homeUrl)); } else { logger.debug(String.format("Validating url '%s'", homeUrl)); URL u = new URL(homeUrl); HttpURLConnection huc = (HttpURLConnection) u.openConnection(); huc.setRequestMethod("GET"); huc.connect(); int code = huc.getResponseCode(); if (code != 200) { throw new CookbookUrlException(errorMsg); } validUrls.add(homeUrl); } } catch (IOException ex) { throw new CookbookUrlException(errorMsg, ex); } } } @Override public String toString() { StringBuilder sb = new StringBuilder(); boolean skipLines = true; // append all lines that appear after 'metadata' in the Berksfile template for (String s : fileLines) { if (!skipLines) { sb.append(s).append(System.lineSeparator()); } if (s.compareToIgnoreCase("metadata") == 0) { skipLines = false; } } return sb.toString(); } }