/** * */ package org.gcube.informationsystem.resourceregistry.instances; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.net.InetAddress; import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; import java.nio.file.FileStore; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.management.AttributeNotFoundException; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.ReflectionException; import org.gcube.informationsystem.model.impl.properties.HeaderImpl; import org.gcube.informationsystem.model.impl.properties.PropagationConstraintImpl; import org.gcube.informationsystem.model.impl.relations.ConsistsOfImpl; import org.gcube.informationsystem.model.reference.entities.Facet; import org.gcube.informationsystem.model.reference.entities.Resource; import org.gcube.informationsystem.model.reference.properties.Header; import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; import org.gcube.informationsystem.model.reference.properties.PropagationConstraint.RemoveConstraint; import org.gcube.informationsystem.model.reference.relations.ConsistsOf; import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.instances.model.entities.ResourceManagement; import org.gcube.informationsystem.utils.ElementMapper; import org.gcube.resourcemanagement.model.impl.entities.facets.CPUFacetImpl; import org.gcube.resourcemanagement.model.impl.entities.facets.EventFacetImpl; import org.gcube.resourcemanagement.model.impl.entities.facets.MemoryFacetImpl; import org.gcube.resourcemanagement.model.impl.entities.facets.NetworkingFacetImpl; import org.gcube.resourcemanagement.model.impl.entities.facets.SimplePropertyFacetImpl; import org.gcube.resourcemanagement.model.impl.entities.facets.SoftwareFacetImpl; import org.gcube.resourcemanagement.model.impl.entities.facets.StateFacetImpl; import org.gcube.resourcemanagement.model.impl.entities.resources.HostingNodeImpl; import org.gcube.resourcemanagement.model.impl.properties.ValueSchemaImpl; import org.gcube.resourcemanagement.model.impl.relations.consistsof.HasPersistentMemoryImpl; import org.gcube.resourcemanagement.model.impl.relations.consistsof.HasVolatileMemoryImpl; import org.gcube.resourcemanagement.model.impl.relations.consistsof.IsIdentifiedByImpl; import org.gcube.resourcemanagement.model.reference.entities.facets.CPUFacet; import org.gcube.resourcemanagement.model.reference.entities.facets.EventFacet; import org.gcube.resourcemanagement.model.reference.entities.facets.MemoryFacet; import org.gcube.resourcemanagement.model.reference.entities.facets.MemoryFacet.MemoryUnit; import org.gcube.resourcemanagement.model.reference.entities.facets.NetworkingFacet; import org.gcube.resourcemanagement.model.reference.entities.facets.SimplePropertyFacet; import org.gcube.resourcemanagement.model.reference.entities.facets.SoftwareFacet; import org.gcube.resourcemanagement.model.reference.entities.facets.StateFacet; import org.gcube.resourcemanagement.model.reference.entities.resources.HostingNode; import org.gcube.resourcemanagement.model.reference.properties.ValueSchema; import org.gcube.resourcemanagement.model.reference.relations.consistsof.HasPersistentMemory; import org.gcube.resourcemanagement.model.reference.relations.consistsof.HasVolatileMemory; import org.gcube.resourcemanagement.model.reference.relations.consistsof.IsIdentifiedBy; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Luca Frosini (ISTI - CNR) */ public class SmartgearResourcesTest extends ERManagementTest { private static Logger logger = LoggerFactory .getLogger(SmartgearResourcesTest.class); public static final String MEMORY_TYPE = "memoryType"; public static final String MEMORY_TYPE_RAM = "RAM"; public static final String MEMORY_TYPE_JVM = "JVM"; public static final String JVM_MAX_MEMORY = "jvmMaxMemory"; @Test public void testHostingNodeOperations() throws ResourceRegistryException, IOException, URISyntaxException { UUID uuid = UUID.randomUUID(); HostingNode hostingNode = new HostingNodeImpl(); Header header = new HeaderImpl(uuid); hostingNode.setHeader(header); NetworkingFacet networkingFacet = new NetworkingFacetImpl(); try { networkingFacet.setIPAddress(InetAddress.getLocalHost() .getHostAddress()); } catch (UnknownHostException e) { logger.warn("unable to detect the IP address of the host"); } networkingFacet.setHostName("pc-frosini.isti.cnr.it"); networkingFacet.setDomainName(getDomain(networkingFacet.getHostName())); networkingFacet.setAdditionalProperty("Port", 8080); PropagationConstraint propagationConstraint = new PropagationConstraintImpl(); propagationConstraint .setRemoveConstraint(RemoveConstraint.cascadeWhenOrphan); IsIdentifiedBy isIdentifiedBy = new IsIdentifiedByImpl<>( hostingNode, networkingFacet, propagationConstraint); hostingNode.addFacet(isIdentifiedBy); List cpuFacets = getCPUFacets(); for (CPUFacet cpuFacet : cpuFacets) { ConsistsOf consistsOf = new ConsistsOfImpl( hostingNode, cpuFacet, propagationConstraint); hostingNode.addFacet(consistsOf); } SoftwareFacet softwareFacet = new SoftwareFacetImpl(); OperatingSystemMXBean mxbean = ManagementFactory .getOperatingSystemMXBean(); softwareFacet.setGroup(mxbean.getName()); // softwareFacet.setGroup(System.getProperty("os.name")); softwareFacet.setName(mxbean.getArch()); // softwareFacet.setName(System.getProperty("os.arch")); softwareFacet.setVersion(mxbean.getVersion()); // softwareFacet.setName(System.getProperty("os.version")); ConsistsOf sfR = new ConsistsOfImpl( hostingNode, softwareFacet, propagationConstraint); hostingNode.addFacet(sfR); SimplePropertyFacet simplePropertyFacet = addEnvironmentVariables(); ConsistsOf spfR = new ConsistsOfImpl( hostingNode, simplePropertyFacet, propagationConstraint); hostingNode.addFacet(spfR); StateFacet stateFacet = getStateFacet(null); hostingNode.addFacet(stateFacet); MemoryFacet ramFacet = getRamInfo(null); HasVolatileMemory hasVolatileRAMMemory = new HasVolatileMemoryImpl( hostingNode, ramFacet, propagationConstraint); hasVolatileRAMMemory .setAdditionalProperty(MEMORY_TYPE, MEMORY_TYPE_RAM); hostingNode.addFacet(hasVolatileRAMMemory); MemoryFacet jvmMemoryFacet = getJVMMemoryInfo(null); HasVolatileMemory hasVolatileJVMMemory = new HasVolatileMemoryImpl( hostingNode, jvmMemoryFacet, propagationConstraint); hasVolatileJVMMemory .setAdditionalProperty(MEMORY_TYPE, MEMORY_TYPE_JVM); hostingNode.addFacet(hasVolatileJVMMemory); MemoryFacet disk = getDiskSpace(null); HasPersistentMemory hasPersistentMemory = new HasPersistentMemoryImpl( hostingNode, disk, propagationConstraint); hostingNode.addFacet(hasPersistentMemory); EventFacet hnEventFacet = new EventFacetImpl(); hnEventFacet.setDate(Calendar.getInstance().getTime()); ValueSchema hnEvent = new ValueSchemaImpl(); hnEvent.setSchema(new URI("Schema")); hnEventFacet.setEvent("Created"); hostingNode.addFacet(hnEventFacet); ResourceManagement resourceManagement = new ResourceManagement(); resourceManagement.setElementType(HostingNode.NAME); resourceManagement.setJson(ElementMapper.marshal(hostingNode)); String json = resourceManagement.create(); HostingNode hostingNodeToUpdate = ElementMapper.unmarshal(HostingNode.class, json); /* Testing convenient methods */ @SuppressWarnings("unchecked") List> hasVolatileMemoryList = hostingNodeToUpdate.getConsistsOf(HasVolatileMemory.class); Assert.assertTrue(hasVolatileMemoryList.size()==2); @SuppressWarnings("unchecked") List> hasPeristentMemoryList = hostingNodeToUpdate.getConsistsOf(HasPersistentMemory.class); Assert.assertTrue(hasPeristentMemoryList.size()==1); @SuppressWarnings("unchecked") List> memoryList = hostingNodeToUpdate.getConsistsOf(ConsistsOf.class, MemoryFacet.class); Assert.assertTrue(memoryList.size()==3); List csfList = hostingNodeToUpdate.getFacets(StateFacet.class); Assert.assertTrue(csfList.size()==1); List spfList = hostingNodeToUpdate.getFacets(SimplePropertyFacet.class); Assert.assertTrue(spfList.size()==1); List sfList = hostingNodeToUpdate.getFacets(SoftwareFacet.class); Assert.assertTrue(sfList.size()==1); List cfList = hostingNodeToUpdate.getFacets(CPUFacet.class); Assert.assertTrue(cfList.size()==cpuFacets.size()); List nfList = hostingNodeToUpdate.getFacets(NetworkingFacet.class); Assert.assertTrue(nfList.size()==1); @SuppressWarnings({ "unchecked", "rawtypes" }) List isbnfList = hostingNodeToUpdate.getConsistsOf(IsIdentifiedBy.class, NetworkingFacet.class); Assert.assertTrue(isbnfList.size()==1); /* Testing convenient methods */ List> consistsOfToRemove = new ArrayList<>(); List> consistsOfList = hostingNodeToUpdate .getConsistsOf(); for (ConsistsOf c : consistsOfList) { if (c.getTarget() instanceof StateFacet) { stateFacet = (StateFacet) c.getTarget(); stateFacet = getStateFacet(stateFacet); continue; } if (c instanceof HasVolatileMemory) { String memoryType = (String) c .getAdditionalProperty(MEMORY_TYPE); if (memoryType.compareTo(MEMORY_TYPE_RAM) == 0) { ramFacet = (MemoryFacet) c.getTarget(); ramFacet = getRamInfo(ramFacet); continue; } if (memoryType.compareTo(MEMORY_TYPE_JVM) == 0) { jvmMemoryFacet = (MemoryFacet) c.getTarget(); jvmMemoryFacet = getJVMMemoryInfo(jvmMemoryFacet); continue; } } if (c instanceof HasPersistentMemory) { disk = (MemoryFacet) c.getTarget(); disk = getDiskSpace(disk); continue; } consistsOfToRemove.add(c); } consistsOfList.removeAll(consistsOfToRemove); resourceManagement = new ResourceManagement(); resourceManagement.setUUID(uuid); resourceManagement.setJson(ElementMapper.marshal(hostingNodeToUpdate)); String updatedHN = resourceManagement.update(); logger.debug("Updated {}", updatedHN); HostingNode updatedHostingNode = ElementMapper.unmarshal(HostingNode.class, updatedHN); logger.debug("Updated Hosting Node {}", updatedHostingNode); resourceManagement = new ResourceManagement(); resourceManagement.setUUID(uuid); resourceManagement.delete(); } private StateFacet getStateFacet(StateFacet stateFacet) { if (stateFacet == null) { stateFacet = new StateFacetImpl(); } stateFacet.setValue("ready"); return stateFacet; } public static final String MESSAGE = "message"; private MemoryFacet getDiskSpace(MemoryFacet memoryFacet) { if (memoryFacet == null) { memoryFacet = new MemoryFacetImpl(); } long free = 0; long total = 0; try { FileStore fileStore = Files.getFileStore(Paths.get("./")); free = fileStore.getUsableSpace() / 1048576; // 1048576 = 1024*1024 // user to convert // bytes in MByte total = fileStore.getTotalSpace() / 1048576; // 1048576 = 1024*1024 // user to convert // bytes in MByte } catch (IOException ioe) { logger.warn("Unable to detect disk space information", ioe); memoryFacet.setAdditionalProperty(MESSAGE, "Unable to detect disk space information."); } memoryFacet.setUnit(MemoryUnit.MB); memoryFacet.setSize(total); memoryFacet.setUsed(total - free); return memoryFacet; } private static final long BYTE_TO_MB = 1024*1024; private MemoryFacet getRamInfo(MemoryFacet memoryFacet) { if (memoryFacet == null) { memoryFacet = new MemoryFacetImpl(); } /* OperatingSystemMXBean mxbean = ManagementFactory.getOperatingSystemMXBean(); com.sun.management.OperatingSystemMXBean sunmxbean = (com.sun.management.OperatingSystemMXBean) mxbean; long freeMemory = sunmxbean.getFreePhysicalMemorySize() / 1048576; // in MB long totalMemory = sunmxbean.getTotalPhysicalMemorySize() / 1048576; // in MB */ MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); long freeMemory; try { freeMemory = Long.parseLong(mBeanServer.getAttribute(new ObjectName("java.lang","type","OperatingSystem"), "FreePhysicalMemorySize").toString()) / BYTE_TO_MB; } catch (NumberFormatException | InstanceNotFoundException | AttributeNotFoundException | MalformedObjectNameException | ReflectionException | MBeanException e) { logger.warn("Unable to get free memory from Operating System. Going to get JVM Memory. Better than nothing"); long allocatedMemory = (Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()); freeMemory = Runtime.getRuntime().maxMemory() - allocatedMemory; } long totalMemory; try { totalMemory = Long.parseLong(mBeanServer.getAttribute(new ObjectName("java.lang","type","OperatingSystem"), "TotalPhysicalMemorySize").toString()) / BYTE_TO_MB; } catch (NumberFormatException | InstanceNotFoundException | AttributeNotFoundException | MalformedObjectNameException | ReflectionException | MBeanException e) { logger.warn("Unable to total memory from Operating System. Going to get JVM Memory. Better than nothing"); totalMemory = Runtime.getRuntime().maxMemory(); } memoryFacet.setUnit(MemoryUnit.MB); memoryFacet.setSize(totalMemory); memoryFacet.setUsed(totalMemory - freeMemory); return memoryFacet; } private MemoryFacet getJVMMemoryInfo(MemoryFacet memoryFacet) { if (memoryFacet == null) { memoryFacet = new MemoryFacetImpl(); } long jvmFreeMemory = Runtime.getRuntime().freeMemory() / 1048576; // 1048576 // = // 1024*1024 // user // to // convert // bytes // in // MByte long jvmTotalMemory = Runtime.getRuntime().totalMemory() / 1048576; // 1048576 // = // 1024*1024 // user // to // convert // bytes // in // MByte long jvmMaxMemory = Runtime.getRuntime().maxMemory() / 1048576; // 1048576 // = // 1024*1024 // user // to // convert // bytes // in // MByte memoryFacet.setUnit(MemoryUnit.MB); memoryFacet.setSize(jvmTotalMemory); memoryFacet.setUsed(jvmTotalMemory - jvmFreeMemory); memoryFacet.setAdditionalProperty(JVM_MAX_MEMORY, jvmMaxMemory); return memoryFacet; } private static String sanitizeKey(String key) { return key.trim().replace(" ", "_"); } private SimplePropertyFacet addEnvironmentVariables() { Map map = new HashMap(); map.putAll(System.getenv()); SimplePropertyFacet simplePropertyFacet = new SimplePropertyFacetImpl(); simplePropertyFacet.setName("ENVIRONMENT_VARIABLES"); simplePropertyFacet.setValue(""); for (Map.Entry entry : map.entrySet()) { String varname = entry.getKey(); if ((varname.compareToIgnoreCase("CLASSPATH") == 0) || (varname.compareToIgnoreCase("PATH") == 0) || (varname.contains("SSH")) || (varname.contains("MAIL")) || (varname.compareToIgnoreCase("LS_COLORS") == 0)) { continue; } simplePropertyFacet.setAdditionalProperty( sanitizeKey(entry.getKey()), entry.getValue()); } simplePropertyFacet.setAdditionalProperty("Java", System.getProperty("java.version")); return simplePropertyFacet; } private static String getDomain(String hostname) { try { Pattern pattern = Pattern .compile("([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})"); Matcher regexMatcher = pattern.matcher(hostname); if (regexMatcher.matches()) { // it's an IP address, nothing to trim return hostname; } return hostname.substring(hostname.indexOf(".") + 1); } catch (Exception e) { logger.warn("Error while getting domain from hostname"); return hostname; } } public static final String CPU_PROCESSOR = "processor"; public static final String CPU_VENDOR_ID = "vendor_id"; public static final String CPU_MODEL_NAME = "model name"; public static final String CPU_CPU_MHZ = "cpu MHz"; public static final String CPU_MODEL_T = "model\t"; public static final String CPU_MODEL_B = "model\b"; public static final String CPU_MODEL_NUMBER = "modelNumber"; public static List getCPUFacets() { List cpuFacets = new ArrayList<>(); File file = new File("/proc/cpuinfo"); if (!file.exists()) { logger.warn("cannot acquire CPU info (no /proc/cpuinfo)"); return cpuFacets; } BufferedReader input = null; try { input = new BufferedReader(new FileReader(file)); String line = null; CPUFacet cpuFacet = null; while ((line = input.readLine()) != null) { if ((line.startsWith(CPU_PROCESSOR))) { // add the current // processor to the map cpuFacet = new CPUFacetImpl(); cpuFacets.add(cpuFacet); } try { if (line.contains(CPU_VENDOR_ID)) { cpuFacet.setVendor(line.split(":")[1].trim()); continue; } } catch (Exception e) { continue; } try { if (line.contains(CPU_MODEL_NAME)) { cpuFacet.setModel(line.split(":")[1].trim()); continue; } } catch (Exception e) { continue; } try { if (line.contains(CPU_CPU_MHZ)) { cpuFacet.setClockSpeed(line.split(":")[1].trim()); continue; } } catch (Exception e) { continue; } try { if ((line.contains(CPU_MODEL_T)) || (line.contains(CPU_MODEL_B))) { cpuFacet.setAdditionalProperty(CPU_MODEL_NUMBER, line.split(":")[1].trim()); continue; } } catch (Exception e) { continue; } try { String[] nameValue = line.split(":"); cpuFacet.setAdditionalProperty(sanitizeKey(nameValue[0]), line.split(":")[1].trim()); } catch (Exception e) { } } } catch (Exception e) { logger.warn("unable to acquire CPU info", e); } finally { if (input != null) { try { input.close(); } catch (IOException e) { logger.warn("unable to close stream", e); } } } return cpuFacets; } }