From 69315db179c8695cc3d7d4c6265a7b4b15ca6b1e Mon Sep 17 00:00:00 2001 From: Giancarlo Panichi Date: Tue, 30 Oct 2018 10:04:46 +0000 Subject: [PATCH] ref 12742: DataMiner - Support Python 3.6 https://support.d4science.org/issues/12742 Python3.6 added git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-analysis/dataminer-pool-manager@173874 82a268e6-3cf1-43bd-a215-b396298e98cf --- .../ansiblebridge/AnsibleBridge.java | 566 +++++++++--------- 1 file changed, 280 insertions(+), 286 deletions(-) diff --git a/src/main/java/org/gcube/dataanalysis/dataminer/poolmanager/ansiblebridge/AnsibleBridge.java b/src/main/java/org/gcube/dataanalysis/dataminer/poolmanager/ansiblebridge/AnsibleBridge.java index 64e7a46..44bf2df 100644 --- a/src/main/java/org/gcube/dataanalysis/dataminer/poolmanager/ansiblebridge/AnsibleBridge.java +++ b/src/main/java/org/gcube/dataanalysis/dataminer/poolmanager/ansiblebridge/AnsibleBridge.java @@ -31,300 +31,294 @@ import org.gcube.dataanalysis.dataminer.poolmanager.datamodel.Dependency; import org.gcube.dataanalysis.dataminer.poolmanager.datamodel.comparator.HostComparator; public class AnsibleBridge { - ***REMOVED***private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AnsibleBridge.class); + ***REMOVED*** private static final org.slf4j.Logger LOGGER = + ***REMOVED*** LoggerFactory.getLogger(AnsibleBridge.class); - - - private String dpmRoot; - -***REMOVED*** public AnsibleBridge() { -***REMOVED*** this(System.getProperty("user.home")+File.separator+"dataminer-pool-manager"); -***REMOVED*** ***REMOVED***this(System.getProperty("/home/gcube/dataminer-pool-manager")); + private String dpmRoot; + + ***REMOVED*** public AnsibleBridge() { + ***REMOVED*** this(System.getProperty("user.home")+File.separator+"dataminer-pool-manager"); + ***REMOVED*** ***REMOVED***this(System.getProperty("/home/gcube/dataminer-pool-manager")); + ***REMOVED*** + ***REMOVED*** ***REMOVED*** + + public AnsibleBridge(String root) { + this.dpmRoot = root; + this.ensureServiceRoot(); ***REMOVED*** -***REMOVED*** ***REMOVED*** - - public AnsibleBridge(String root) { - this.dpmRoot = root; - this.ensureServiceRoot(); - ***REMOVED*** - - private void ensureServiceRoot() { - ***REMOVED*** generate root - new File(dpmRoot).mkdirs(); - ***REMOVED*** 'template' is for template roles - ***REMOVED***this.getTemplatesDir().mkdirs(); - ***REMOVED*** 'static' is for custom roles - ***REMOVED***this.getCustomDir().mkdirs(); - ***REMOVED*** 'work' is for temporary working directories - this.getWorkDir().mkdirs(); - ***REMOVED*** - - private File getWorkDir() { - return new File(this.dpmRoot, "work"); - ***REMOVED*** - -***REMOVED*** private String getTemplatesDir() { -***REMOVED*** String input = null; -***REMOVED*** input = AnsibleBridge.class.getClassLoader().getResource("templates").getPath(); -***REMOVED*** return input; -***REMOVED*** ***REMOVED*** -***REMOVED*** -***REMOVED*** -***REMOVED*** private String getCustomDir() { -***REMOVED*** String input = null; -***REMOVED*** input = AnsibleBridge.class.getClassLoader().getResource("custom").getPath(); -***REMOVED*** return input; -***REMOVED*** ***REMOVED*** - - - - - - - public AnsibleWorker createWorker(Algorithm algorithm, Cluster dataminerCluster, boolean includeAlgorithmDependencies, String user) throws IOException { - File workerRoot = new File(this.getWorkDir(), UUID.randomUUID().toString()); - AnsibleWorker worker = new AnsibleWorker(workerRoot); - - List algoRoles = new Vector<>(); - - ***REMOVED*** add algorithms and dependencies to the worker - for (Role r : this.generateRoles(algorithm,includeAlgorithmDependencies)) { - algoRoles.add(r); - worker.addRole(r); - ***REMOVED*** - - ***REMOVED***to comment the for in case of just install algo - if(includeAlgorithmDependencies){ - for (Dependency d : algorithm.getDependencies()) { - for (Role r : this.generateRoles(d)) { - worker.addRole(r); - ***REMOVED*** - ***REMOVED*** - ***REMOVED*** - - - ***REMOVED*** add static roles - for(Role r:this.getStaticRoleManager().getStaticRoles()) { - worker.addRole(r); - ***REMOVED*** - - ***REMOVED*** generate the inventory - Inventory inventory = new Inventory(); - for (Host h : dataminerCluster.getHosts()) { - AnsibleHost ah = new AnsibleHost(h.getName()); - inventory.addHost(ah, "universe"); - inventory.addHost(ah, "d4science"); - ***REMOVED*** - worker.setInventory(inventory); - - ***REMOVED*** generate the playbook - Playbook playbook = new Playbook(); - playbook.setRemote_user(user); - playbook.applyTo("universe"); - for(Role r:algoRoles) { - ***REMOVED*** add only 'add' roles - if(!r.getName().endsWith("remove")) { - playbook.addRole(r.getName()); - ***REMOVED*** - ***REMOVED*** - - worker.setPlaybook(playbook); - - return worker; - ***REMOVED*** - - - public void printInventoryByDomainAndSets(Collection clusters) { - Map> inventory = new TreeMap<>(); - for(Cluster cluster:clusters) { - for(AlgorithmSet as:cluster.getAlgorithmSets()) { - String asName = as.getName(); - for(Host h:cluster.getHosts()) { - String domain = h.getDomain().getName(); - String key = String.format("[%s@%s]", asName, domain); - Set hosts = inventory.get(key); - if(hosts==null) { - hosts = new TreeSet<>(new HostComparator()); - inventory.put(key, hosts); - ***REMOVED*** - hosts.add(h); - ***REMOVED*** - - ***REMOVED*** - ***REMOVED*** - for(String key:inventory.keySet()) { - System.out.println(key); - Collection hosts = inventory.get(key); - for(Host h:hosts) { - System.out.println(h.getName()+"."+h.getDomain().getName()); - ***REMOVED*** - System.out.println(); - ***REMOVED*** - ***REMOVED*** - - - public void printInventoryBySets(Collection clusters) { - Map> inventory = new TreeMap<>(); - for (Cluster cluster : clusters) { - for (AlgorithmSet as : cluster.getAlgorithmSets()) { - String asName = as.getName(); - for (Host h : cluster.getHosts()) { - String key = String.format("[%s]", asName); - Set hosts = inventory.get(key); - if (hosts == null) { - hosts = new TreeSet<>(new HostComparator()); - inventory.put(key, hosts); - ***REMOVED*** - hosts.add(h); - ***REMOVED*** - - ***REMOVED*** - ***REMOVED*** - for (String key : inventory.keySet()) { - System.out.println(key); - Collection hosts = inventory.get(key); - for (Host h : hosts) { - System.out.println(h.getName()+"."+h.getDomain().getName()); - ***REMOVED*** - System.out.println(); - ***REMOVED*** - ***REMOVED*** - -***REMOVED*** public AnsibleWorker applyAlgorithmSetToCluster(AlgorithmSet as, Cluster cluster, /*boolean updateSVN,*/ boolean test) throws IOException, InterruptedException, SVNException { -***REMOVED*** -***REMOVED*** -***REMOVED*** return applyAlgorithmSetToCluster (as,cluster,UUID.randomUUID().toString(),/*updateSVN,*/ test); -***REMOVED*** ***REMOVED*** - -***REMOVED*** public AnsibleWorker applyAlgorithmSetToCluster(AlgorithmSet as, Cluster cluster,String uuid, /*boolean updateSVN,*/ boolean test) throws IOException, InterruptedException, SVNException { -***REMOVED*** AnsibleWorker worker = new AnsibleWorker(new File(this.getWorkDir(), uuid)); + private void ensureServiceRoot() { + ***REMOVED*** generate root + new File(dpmRoot).mkdirs(); + ***REMOVED*** 'template' is for template roles + ***REMOVED*** this.getTemplatesDir().mkdirs(); + ***REMOVED*** 'static' is for custom roles + ***REMOVED*** this.getCustomDir().mkdirs(); + ***REMOVED*** 'work' is for temporary working directories + this.getWorkDir().mkdirs(); ***REMOVED*** -***REMOVED*** -***REMOVED*** List algoRoles = new Vector<>(); -***REMOVED*** -***REMOVED*** ***REMOVED*** add algorithms and dependencies to the worker -***REMOVED*** for (Algorithm a : as.getAlgorithms()) { -***REMOVED*** for (Role r : this.generateRoles(a)) { -***REMOVED*** algoRoles.add(r); -***REMOVED*** worker.addRole(r); -***REMOVED*** ***REMOVED*** -***REMOVED*** ***REMOVED***to comment the for in case of just install algo -***REMOVED*** if(test){ -***REMOVED*** for (Dependency d : a.getDependencies()) { -***REMOVED*** for (Role r : this.generateRoles(d)) { -***REMOVED*** worker.addRole(r); -***REMOVED*** ***REMOVED*** -***REMOVED*** ***REMOVED*** -***REMOVED*** ***REMOVED*** -***REMOVED*** ***REMOVED*** -***REMOVED*** -***REMOVED*** ***REMOVED*** add static roles -***REMOVED*** for(Role r:this.getStaticRoleManager().getStaticRoles()) { -***REMOVED*** worker.addRole(r); -***REMOVED*** ***REMOVED*** -***REMOVED*** -***REMOVED*** ***REMOVED*** generate the inventory -***REMOVED*** Inventory inventory = new Inventory(); -***REMOVED*** for (Host h : cluster.getHosts()) { -***REMOVED*** AnsibleHost ah = new AnsibleHost(h.getName()); -***REMOVED*** inventory.addHost(ah, "universe"); -***REMOVED*** inventory.addHost(ah, "d4science"); -***REMOVED*** ***REMOVED*** -***REMOVED*** worker.setInventory(inventory); -***REMOVED*** -***REMOVED*** ***REMOVED*** generate the playbook -***REMOVED*** Playbook playbook = new Playbook(); -***REMOVED*** if(test){ -***REMOVED*** playbook.setRemote_user("root");***REMOVED*** -***REMOVED*** playbook.setRemote_user("gcube"); -***REMOVED*** playbook.applyTo("universe"); -***REMOVED*** for(Role r:algoRoles) { -***REMOVED*** ***REMOVED*** add only 'add' roles -***REMOVED*** if(!r.getName().endsWith("remove")) { -***REMOVED*** playbook.addRole(r.getName()); -***REMOVED*** ***REMOVED*** -***REMOVED*** ***REMOVED*** -***REMOVED*** -***REMOVED*** worker.setPlaybook(playbook); -***REMOVED*** -***REMOVED*** ***REMOVED*** execute and save log locally -***REMOVED*** ***REMOVED***PrintStream console = System.out; -***REMOVED*** File path = new File(worker.getWorkdir() + File.separator + "logs"); -***REMOVED*** path.mkdirs(); -***REMOVED*** File n = new File(path + File.separator + worker.getWorkerId()); -***REMOVED*** FileOutputStream fos = new FileOutputStream(n); -***REMOVED*** PrintStream ps = new PrintStream(fos); -***REMOVED*** -***REMOVED*** ***REMOVED***System.setErr(console); -***REMOVED*** -***REMOVED*** worker.apply(as,ps,test); -***REMOVED*** ***REMOVED***System.setOut(console); -***REMOVED*** ***REMOVED***worker.apply(); -***REMOVED*** System.out.println("Log stored to to " + n.getAbsolutePath()); -***REMOVED*** -***REMOVED*** ***REMOVED*** destroy the worker -***REMOVED*** worker.destroy(); -***REMOVED*** return worker; -***REMOVED*** ***REMOVED*** - - - - private TemplateManager getTemplateManager() { - return new TemplateManager(); - ***REMOVED*** - private CustomRoleManager getCustomRoleManager() { - return new CustomRoleManager(); - ***REMOVED*** + private File getWorkDir() { + return new File(this.dpmRoot, "work"); +***REMOVED*** - private StaticRoleManager getStaticRoleManager() { - return new StaticRoleManager(); - ***REMOVED*** + ***REMOVED*** private String getTemplatesDir() { + ***REMOVED*** String input = null; + ***REMOVED*** input = + ***REMOVED*** AnsibleBridge.class.getClassLoader().getResource("templates").getPath(); + ***REMOVED*** return input; + ***REMOVED*** ***REMOVED*** + ***REMOVED*** + ***REMOVED*** + ***REMOVED*** private String getCustomDir() { + ***REMOVED*** String input = null; + ***REMOVED*** input = + ***REMOVED*** AnsibleBridge.class.getClassLoader().getResource("custom").getPath(); + ***REMOVED*** return input; + ***REMOVED*** ***REMOVED*** - /** - * Generate all roles for this dependency - * @param dep Dependency - * @return Collection of Roles - */ - public Collection generateRoles(Dependency dep) { - Collection roles = new Vector<>(); - - - if("os".equalsIgnoreCase(dep.getType())) { - OSDependencyPackage pkg = new OSDependencyPackage(dep); - if(pkg!=null) { - roles.addAll(pkg.getRoles(this.getTemplateManager())); - ***REMOVED*** - - ***REMOVED*** else if("custom".equalsIgnoreCase(dep.getType())) { - CustomDependencyPackage pkg = new CustomDependencyPackage(dep); - if(pkg!=null) { - roles.addAll(pkg.getRoles(this.getCustomRoleManager())); - ***REMOVED*** - ***REMOVED*** - - else if("github".equalsIgnoreCase(dep.getType())) { - CranDependencyPackage pkg = new CranDependencyPackage(dep); - if(pkg!=null) { - roles.addAll(pkg.getRoles(this.getTemplateManager())); - ***REMOVED*** - ***REMOVED*** - else if("cran".equalsIgnoreCase(dep.getType())) { - CranDependencyPackage pkg = new CranDependencyPackage(dep); - if(pkg!=null) { - roles.addAll(pkg.getRoles(this.getTemplateManager())); - ***REMOVED*** - - - ***REMOVED*** - return roles; - ***REMOVED*** + public AnsibleWorker createWorker(Algorithm algorithm, Cluster dataminerCluster, + boolean includeAlgorithmDependencies, String user) throws IOException { + File workerRoot = new File(this.getWorkDir(), UUID.randomUUID().toString()); + AnsibleWorker worker = new AnsibleWorker(workerRoot); - public Collection generateRoles(Algorithm a,boolean includeAlgorithmDependencies) { - AlgorithmPackage pkg = new AlgorithmPackage(a,includeAlgorithmDependencies); - return pkg.getRoles(this.getTemplateManager()); + List algoRoles = new Vector<>(); - ***REMOVED*** + ***REMOVED*** add algorithms and dependencies to the worker + for (Role r : this.generateRoles(algorithm, includeAlgorithmDependencies)) { + algoRoles.add(r); + worker.addRole(r); + ***REMOVED*** + + ***REMOVED*** to comment the for in case of just install algo + if (includeAlgorithmDependencies) { + for (Dependency d : algorithm.getDependencies()) { + for (Role r : this.generateRoles(d)) { + worker.addRole(r); + ***REMOVED*** + ***REMOVED*** + ***REMOVED*** + + ***REMOVED*** add static roles + for (Role r : this.getStaticRoleManager().getStaticRoles()) { + worker.addRole(r); + ***REMOVED*** + + ***REMOVED*** generate the inventory + Inventory inventory = new Inventory(); + for (Host h : dataminerCluster.getHosts()) { + AnsibleHost ah = new AnsibleHost(h.getName()); + inventory.addHost(ah, "universe"); + inventory.addHost(ah, "d4science"); + ***REMOVED*** + worker.setInventory(inventory); + + ***REMOVED*** generate the playbook + Playbook playbook = new Playbook(); + playbook.setRemote_user(user); + playbook.applyTo("universe"); + for (Role r : algoRoles) { + ***REMOVED*** add only 'add' roles + if (!r.getName().endsWith("remove")) { + playbook.addRole(r.getName()); + ***REMOVED*** + ***REMOVED*** + + worker.setPlaybook(playbook); + + return worker; +***REMOVED*** + + public void printInventoryByDomainAndSets(Collection clusters) { + Map> inventory = new TreeMap<>(); + for (Cluster cluster : clusters) { + for (AlgorithmSet as : cluster.getAlgorithmSets()) { + String asName = as.getName(); + for (Host h : cluster.getHosts()) { + String domain = h.getDomain().getName(); + String key = String.format("[%s@%s]", asName, domain); + Set hosts = inventory.get(key); + if (hosts == null) { + hosts = new TreeSet<>(new HostComparator()); + inventory.put(key, hosts); + ***REMOVED*** + hosts.add(h); + ***REMOVED*** + + ***REMOVED*** + ***REMOVED*** + for (String key : inventory.keySet()) { + System.out.println(key); + Collection hosts = inventory.get(key); + for (Host h : hosts) { + System.out.println(h.getName() + "." + h.getDomain().getName()); + ***REMOVED*** + System.out.println(); + ***REMOVED*** +***REMOVED*** + + public void printInventoryBySets(Collection clusters) { + Map> inventory = new TreeMap<>(); + for (Cluster cluster : clusters) { + for (AlgorithmSet as : cluster.getAlgorithmSets()) { + String asName = as.getName(); + for (Host h : cluster.getHosts()) { + String key = String.format("[%s]", asName); + Set hosts = inventory.get(key); + if (hosts == null) { + hosts = new TreeSet<>(new HostComparator()); + inventory.put(key, hosts); + ***REMOVED*** + hosts.add(h); + ***REMOVED*** + + ***REMOVED*** + ***REMOVED*** + for (String key : inventory.keySet()) { + System.out.println(key); + Collection hosts = inventory.get(key); + for (Host h : hosts) { + System.out.println(h.getName() + "." + h.getDomain().getName()); + ***REMOVED*** + System.out.println(); + ***REMOVED*** +***REMOVED*** + + ***REMOVED*** public AnsibleWorker applyAlgorithmSetToCluster(AlgorithmSet as, Cluster + ***REMOVED*** cluster, /*boolean updateSVN,*/ boolean test) throws IOException, + ***REMOVED*** InterruptedException, SVNException { + ***REMOVED*** + ***REMOVED*** + ***REMOVED*** return applyAlgorithmSetToCluster + ***REMOVED*** (as,cluster,UUID.randomUUID().toString(),/*updateSVN,*/ test); + ***REMOVED*** ***REMOVED*** + + ***REMOVED*** public AnsibleWorker applyAlgorithmSetToCluster(AlgorithmSet as, Cluster + ***REMOVED*** cluster,String uuid, /*boolean updateSVN,*/ boolean test) throws + ***REMOVED*** IOException, InterruptedException, SVNException { + ***REMOVED*** AnsibleWorker worker = new AnsibleWorker(new File(this.getWorkDir(), + ***REMOVED*** uuid)); + ***REMOVED*** + ***REMOVED*** + ***REMOVED*** List algoRoles = new Vector<>(); + ***REMOVED*** + ***REMOVED*** ***REMOVED*** add algorithms and dependencies to the worker + ***REMOVED*** for (Algorithm a : as.getAlgorithms()) { + ***REMOVED*** for (Role r : this.generateRoles(a)) { + ***REMOVED*** algoRoles.add(r); + ***REMOVED*** worker.addRole(r); + ***REMOVED*** ***REMOVED*** + ***REMOVED*** ***REMOVED***to comment the for in case of just install algo + ***REMOVED*** if(test){ + ***REMOVED*** for (Dependency d : a.getDependencies()) { + ***REMOVED*** for (Role r : this.generateRoles(d)) { + ***REMOVED*** worker.addRole(r); + ***REMOVED*** ***REMOVED*** + ***REMOVED*** ***REMOVED*** + ***REMOVED*** ***REMOVED*** + ***REMOVED*** ***REMOVED*** + ***REMOVED*** + ***REMOVED*** ***REMOVED*** add static roles + ***REMOVED*** for(Role r:this.getStaticRoleManager().getStaticRoles()) { + ***REMOVED*** worker.addRole(r); + ***REMOVED*** ***REMOVED*** + ***REMOVED*** + ***REMOVED*** ***REMOVED*** generate the inventory + ***REMOVED*** Inventory inventory = new Inventory(); + ***REMOVED*** for (Host h : cluster.getHosts()) { + ***REMOVED*** AnsibleHost ah = new AnsibleHost(h.getName()); + ***REMOVED*** inventory.addHost(ah, "universe"); + ***REMOVED*** inventory.addHost(ah, "d4science"); + ***REMOVED*** ***REMOVED*** + ***REMOVED*** worker.setInventory(inventory); + ***REMOVED*** + ***REMOVED*** ***REMOVED*** generate the playbook + ***REMOVED*** Playbook playbook = new Playbook(); + ***REMOVED*** if(test){ + ***REMOVED*** playbook.setRemote_user("root");***REMOVED*** + ***REMOVED*** playbook.setRemote_user("gcube"); + ***REMOVED*** playbook.applyTo("universe"); + ***REMOVED*** for(Role r:algoRoles) { + ***REMOVED*** ***REMOVED*** add only 'add' roles + ***REMOVED*** if(!r.getName().endsWith("remove")) { + ***REMOVED*** playbook.addRole(r.getName()); + ***REMOVED*** ***REMOVED*** + ***REMOVED*** ***REMOVED*** + ***REMOVED*** + ***REMOVED*** worker.setPlaybook(playbook); + ***REMOVED*** + ***REMOVED*** ***REMOVED*** execute and save log locally + ***REMOVED*** ***REMOVED***PrintStream console = System.out; + ***REMOVED*** File path = new File(worker.getWorkdir() + File.separator + "logs"); + ***REMOVED*** path.mkdirs(); + ***REMOVED*** File n = new File(path + File.separator + worker.getWorkerId()); + ***REMOVED*** FileOutputStream fos = new FileOutputStream(n); + ***REMOVED*** PrintStream ps = new PrintStream(fos); + ***REMOVED*** + ***REMOVED*** ***REMOVED***System.setErr(console); + ***REMOVED*** + ***REMOVED*** worker.apply(as,ps,test); + ***REMOVED*** ***REMOVED***System.setOut(console); + ***REMOVED*** ***REMOVED***worker.apply(); + ***REMOVED*** System.out.println("Log stored to to " + n.getAbsolutePath()); + ***REMOVED*** + ***REMOVED*** ***REMOVED*** destroy the worker + ***REMOVED*** worker.destroy(); + ***REMOVED*** return worker; + ***REMOVED*** ***REMOVED*** + + private TemplateManager getTemplateManager() { + return new TemplateManager(); +***REMOVED*** + + private CustomRoleManager getCustomRoleManager() { + return new CustomRoleManager(); +***REMOVED*** + + private StaticRoleManager getStaticRoleManager() { + return new StaticRoleManager(); +***REMOVED*** + + /** + * Generate all roles for this dependency + * + * @param dep + * Dependency + * @return Collection of Roles + */ + public Collection generateRoles(Dependency dep) { + Collection roles = new Vector<>(); + + if ("os".equalsIgnoreCase(dep.getType())) { + OSDependencyPackage pkg = new OSDependencyPackage(dep); + if (pkg != null) { + roles.addAll(pkg.getRoles(this.getTemplateManager())); + ***REMOVED*** + + ***REMOVED*** else if ("custom".equalsIgnoreCase(dep.getType())) { + CustomDependencyPackage pkg = new CustomDependencyPackage(dep); + if (pkg != null) { + roles.addAll(pkg.getRoles(this.getCustomRoleManager())); + ***REMOVED*** + ***REMOVED*** else if ("github".equalsIgnoreCase(dep.getType())) { + CranDependencyPackage pkg = new CranDependencyPackage(dep); + if (pkg != null) { + roles.addAll(pkg.getRoles(this.getTemplateManager())); + ***REMOVED*** + ***REMOVED*** else if ("cran".equalsIgnoreCase(dep.getType())) { + CranDependencyPackage pkg = new CranDependencyPackage(dep); + if (pkg != null) { + roles.addAll(pkg.getRoles(this.getTemplateManager())); + ***REMOVED*** + + ***REMOVED*** + return roles; +***REMOVED*** + + public Collection generateRoles(Algorithm a, boolean includeAlgorithmDependencies) { + AlgorithmPackage pkg = new AlgorithmPackage(a, includeAlgorithmDependencies); + return pkg.getRoles(this.getTemplateManager()); + +***REMOVED*** ***REMOVED***