mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	Merge remote-tracking branch 'apache/4.20'
This commit is contained in:
		
						commit
						22bf8fd5d1
					
				| @ -46,6 +46,7 @@ import java.util.stream.Collectors; | |||||||
| 
 | 
 | ||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| 
 | 
 | ||||||
|  | import com.cloud.utils.DateUtil; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; | import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; | import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; | import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; | ||||||
| @ -170,10 +171,10 @@ import com.codahale.metrics.jvm.GarbageCollectorMetricSet; | |||||||
| import com.codahale.metrics.jvm.MemoryUsageGaugeSet; | import com.codahale.metrics.jvm.MemoryUsageGaugeSet; | ||||||
| import com.codahale.metrics.jvm.ThreadStatesGaugeSet; | import com.codahale.metrics.jvm.ThreadStatesGaugeSet; | ||||||
| import com.google.gson.Gson; | import com.google.gson.Gson; | ||||||
|  | import com.google.gson.GsonBuilder; | ||||||
| import com.google.gson.JsonElement; | import com.google.gson.JsonElement; | ||||||
| import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||||
| import com.google.gson.JsonParseException; | import com.google.gson.JsonParseException; | ||||||
| import com.google.gson.reflect.TypeToken; |  | ||||||
| import com.sun.management.OperatingSystemMXBean; | import com.sun.management.OperatingSystemMXBean; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -294,6 +295,9 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc | |||||||
|     private static StatsCollector s_instance = null; |     private static StatsCollector s_instance = null; | ||||||
| 
 | 
 | ||||||
|     private static Gson gson = new Gson(); |     private static Gson gson = new Gson(); | ||||||
|  |     private static Gson msStatsGson = new GsonBuilder() | ||||||
|  |             .setDateFormat(DateUtil.ZONED_DATETIME_FORMAT) | ||||||
|  |             .create(); | ||||||
| 
 | 
 | ||||||
|     private ScheduledExecutorService _executor = null; |     private ScheduledExecutorService _executor = null; | ||||||
|     @Inject |     @Inject | ||||||
| @ -739,7 +743,6 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc | |||||||
|              dbStats.put(uptime, (Long.valueOf(stats.get(uptime)))); |              dbStats.put(uptime, (Long.valueOf(stats.get(uptime)))); | ||||||
|          } |          } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|          @Override |          @Override | ||||||
|          protected Point createInfluxDbPoint(Object metricsObject) { |          protected Point createInfluxDbPoint(Object metricsObject) { | ||||||
|              return null; |              return null; | ||||||
| @ -759,7 +762,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc | |||||||
|                 msHostStatsEntry = getDataFrom(mshost); |                 msHostStatsEntry = getDataFrom(mshost); | ||||||
|                 managementServerHostStats.put(mshost.getUuid(), msHostStatsEntry); |                 managementServerHostStats.put(mshost.getUuid(), msHostStatsEntry); | ||||||
|                 // send to other hosts |                 // send to other hosts | ||||||
|                 clusterManager.publishStatus(gson.toJson(msHostStatsEntry)); |                 clusterManager.publishStatus(msStatsGson.toJson(msHostStatsEntry)); | ||||||
|             } catch (Throwable t) { |             } catch (Throwable t) { | ||||||
|                 // pokemon catch to make sure the thread stays running |                 // pokemon catch to make sure the thread stays running | ||||||
|                 logger.error("Error trying to retrieve management server host statistics", t); |                 logger.error("Error trying to retrieve management server host statistics", t); | ||||||
| @ -940,12 +943,12 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc | |||||||
|                 logger.info(String.format("used memory from /proc: %d", newEntry.getSystemMemoryUsed())); |                 logger.info(String.format("used memory from /proc: %d", newEntry.getSystemMemoryUsed())); | ||||||
|             } |             } | ||||||
|             try { |             try { | ||||||
|                 String bootTime = Script.runSimpleBashScript("uptime -s"); |                 String bootTime = Script.runSimpleBashScript("date -d @$(grep btime /proc/stat | awk '{print $2}') '+%Y-%m-%d %H:%M:%S'"); | ||||||
|                 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.ENGLISH); |                 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH); | ||||||
|                 Date date = formatter.parse(bootTime); |                 Date date = formatter.parse(bootTime); | ||||||
|                 newEntry.setSystemBootTime(date); |                 newEntry.setSystemBootTime(date); | ||||||
|             } catch (ParseException e) { |             } catch (ParseException e) { | ||||||
|                 logger.error("can not retrieve system uptime"); |                 logger.error("can not retrieve system uptime", e); | ||||||
|             } |             } | ||||||
|             String maxuse = Script.runSimpleBashScript(String.format("ps -o vsz= %d", newEntry.getPid())); |             String maxuse = Script.runSimpleBashScript(String.format("ps -o vsz= %d", newEntry.getPid())); | ||||||
|             newEntry.setSystemMemoryVirtualSize(Long.parseLong(maxuse) * 1024); |             newEntry.setSystemMemoryVirtualSize(Long.parseLong(maxuse) * 1024); | ||||||
| @ -1161,9 +1164,9 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc | |||||||
|                 logger.debug(String.format("StatusUpdate from %s, json: %s", pdu.getSourcePeer(), pdu.getJsonPackage())); |                 logger.debug(String.format("StatusUpdate from %s, json: %s", pdu.getSourcePeer(), pdu.getJsonPackage())); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             ManagementServerHostStatsEntry hostStatsEntry = null; |             ManagementServerHostStatsEntry hostStatsEntry; | ||||||
|             try { |             try { | ||||||
|                 hostStatsEntry = gson.fromJson(pdu.getJsonPackage(),new TypeToken<ManagementServerHostStatsEntry>(){}.getType()); |                 hostStatsEntry = msStatsGson.fromJson(pdu.getJsonPackage(), ManagementServerHostStatsEntry.class); | ||||||
|                 managementServerHostStats.put(hostStatsEntry.getManagementServerHostUuid(), hostStatsEntry); |                 managementServerHostStats.put(hostStatsEntry.getManagementServerHostUuid(), hostStatsEntry); | ||||||
| 
 | 
 | ||||||
|                 // Update peer state to Up in mshost_peer |                 // Update peer state to Up in mshost_peer | ||||||
|  | |||||||
| @ -20,8 +20,10 @@ package com.cloud.server; | |||||||
| 
 | 
 | ||||||
| import static org.mockito.Mockito.when; | import static org.mockito.Mockito.when; | ||||||
| 
 | 
 | ||||||
|  | import java.lang.reflect.Field; | ||||||
| import java.net.URI; | import java.net.URI; | ||||||
| import java.net.URISyntaxException; | import java.net.URISyntaxException; | ||||||
|  | import java.text.SimpleDateFormat; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.Date; | import java.util.Date; | ||||||
| @ -33,6 +35,8 @@ import java.util.TreeMap; | |||||||
| import java.util.concurrent.ConcurrentHashMap; | import java.util.concurrent.ConcurrentHashMap; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
| 
 | 
 | ||||||
|  | import com.cloud.utils.DateUtil; | ||||||
|  | import com.google.gson.JsonSyntaxException; | ||||||
| import org.apache.cloudstack.framework.config.ConfigKey; | import org.apache.cloudstack.framework.config.ConfigKey; | ||||||
| import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; | import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; | ||||||
| import org.apache.commons.collections.CollectionUtils; | import org.apache.commons.collections.CollectionUtils; | ||||||
| @ -116,6 +120,8 @@ public class StatsCollectorTest { | |||||||
| 
 | 
 | ||||||
|     private static Gson gson = new Gson(); |     private static Gson gson = new Gson(); | ||||||
| 
 | 
 | ||||||
|  |     private Gson msStatsGson; | ||||||
|  | 
 | ||||||
|     private MockedStatic<InfluxDBFactory> influxDBFactoryMocked; |     private MockedStatic<InfluxDBFactory> influxDBFactoryMocked; | ||||||
| 
 | 
 | ||||||
|     private AutoCloseable closeable; |     private AutoCloseable closeable; | ||||||
| @ -125,6 +131,9 @@ public class StatsCollectorTest { | |||||||
|         closeable = MockitoAnnotations.openMocks(this); |         closeable = MockitoAnnotations.openMocks(this); | ||||||
|         statsCollector.vmStatsDao = vmStatsDaoMock; |         statsCollector.vmStatsDao = vmStatsDaoMock; | ||||||
|         statsCollector.volumeStatsDao = volumeStatsDao; |         statsCollector.volumeStatsDao = volumeStatsDao; | ||||||
|  |         Field msStatsGsonField = StatsCollector.class.getDeclaredField("msStatsGson"); | ||||||
|  |         msStatsGsonField.setAccessible(true); | ||||||
|  |         msStatsGson = (Gson) msStatsGsonField.get(null); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @After |     @After | ||||||
| @ -612,4 +621,107 @@ public class StatsCollectorTest { | |||||||
|         Mockito.verify(mockPool, Mockito.never()).setCapacityIops(Mockito.anyLong()); |         Mockito.verify(mockPool, Mockito.never()).setCapacityIops(Mockito.anyLong()); | ||||||
|         Mockito.verify(mockPool, Mockito.never()).setUsedIops(Mockito.anyLong()); |         Mockito.verify(mockPool, Mockito.never()).setUsedIops(Mockito.anyLong()); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testGsonDateFormatSerialization() { | ||||||
|  |         Date now = new Date(); | ||||||
|  |         TestClass testObj = new TestClass("TestString", 999, now); | ||||||
|  |         String json = msStatsGson.toJson(testObj); | ||||||
|  | 
 | ||||||
|  |         Assert.assertTrue(json.contains("TestString")); | ||||||
|  |         Assert.assertTrue(json.contains("999")); | ||||||
|  |         String expectedDate = new SimpleDateFormat(DateUtil.ZONED_DATETIME_FORMAT).format(now); | ||||||
|  |         Assert.assertTrue(json.contains(expectedDate)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testGsonDateFormatDeserializationWithSameDateFormat() throws Exception { | ||||||
|  |         String json = "{\"str\":\"TestString\",\"num\":999,\"date\":\"2025-08-22T15:39:43+0000\"}"; | ||||||
|  |         TestClass testObj = msStatsGson.fromJson(json, TestClass.class); | ||||||
|  | 
 | ||||||
|  |         Assert.assertEquals("TestString", testObj.getStr()); | ||||||
|  |         Assert.assertEquals(999, testObj.getNum()); | ||||||
|  |         Date expectedDate = new SimpleDateFormat(DateUtil.ZONED_DATETIME_FORMAT).parse("2025-08-22T15:39:43+0000"); | ||||||
|  |         Assert.assertEquals(expectedDate, testObj.getDate()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test (expected = JsonSyntaxException.class) | ||||||
|  |     public void testGsonDateFormatDeserializationWithDifferentDateFormat() throws Exception { | ||||||
|  |         String json = "{\"str\":\"TestString\",\"num\":999,\"date\":\"22/08/2025T15:39:43+0000\"}"; | ||||||
|  |         msStatsGson.fromJson(json, TestClass.class); | ||||||
|  |         /* Deserialization throws the below exception: | ||||||
|  |         com.google.gson.JsonSyntaxException: 22/08/2025T15:39:43+0000 | ||||||
|  |             at com.google.gson.DefaultTypeAdapters$DefaultDateTypeAdapter.deserializeToDate(DefaultTypeAdapters.java:376) | ||||||
|  |             at com.google.gson.DefaultTypeAdapters$DefaultDateTypeAdapter.deserialize(DefaultTypeAdapters.java:351) | ||||||
|  |             at com.google.gson.DefaultTypeAdapters$DefaultDateTypeAdapter.deserialize(DefaultTypeAdapters.java:307) | ||||||
|  |             at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:92) | ||||||
|  |             at com.google.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler(JsonObjectDeserializationVisitor.java:117) | ||||||
|  |             at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:63) | ||||||
|  |             at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120) | ||||||
|  |             at com.google.gson.JsonDeserializationContextDefault.fromJsonObject(JsonDeserializationContextDefault.java:76) | ||||||
|  |             at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:54) | ||||||
|  |             at com.google.gson.Gson.fromJson(Gson.java:551) | ||||||
|  |             at com.google.gson.Gson.fromJson(Gson.java:498) | ||||||
|  |             at com.google.gson.Gson.fromJson(Gson.java:467) | ||||||
|  |             at com.google.gson.Gson.fromJson(Gson.java:417) | ||||||
|  |             at com.google.gson.Gson.fromJson(Gson.java:389) | ||||||
|  |             at com.cloud.serializer.GsonHelperTest.testGsonDateFormatDeserializationWithDifferentDateFormat(GsonHelperTest.java:113) | ||||||
|  |             at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) | ||||||
|  |             at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) | ||||||
|  |             at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) | ||||||
|  |             at java.base/java.lang.reflect.Method.invoke(Method.java:566) | ||||||
|  |             at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) | ||||||
|  |             at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) | ||||||
|  |             at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) | ||||||
|  |             at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) | ||||||
|  |             at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) | ||||||
|  |             at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) | ||||||
|  |             at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) | ||||||
|  |             at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) | ||||||
|  |             at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) | ||||||
|  |             at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) | ||||||
|  |             at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) | ||||||
|  |             at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) | ||||||
|  |             at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) | ||||||
|  |             at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) | ||||||
|  |             at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) | ||||||
|  |             at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) | ||||||
|  |             at org.junit.runners.ParentRunner.run(ParentRunner.java:413) | ||||||
|  |             at org.junit.runner.JUnitCore.run(JUnitCore.java:137) | ||||||
|  |             at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) | ||||||
|  |             at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) | ||||||
|  |             at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) | ||||||
|  |             at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) | ||||||
|  |             at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:231) | ||||||
|  |             at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55) | ||||||
|  |         Caused by: java.text.ParseException: Unparseable date: "22/08/2025T15:39:43+0000" | ||||||
|  |             at java.base/java.text.DateFormat.parse(DateFormat.java:395) | ||||||
|  |             at com.google.gson.DefaultTypeAdapters$DefaultDateTypeAdapter.deserializeToDate(DefaultTypeAdapters.java:374) | ||||||
|  |             ... 42 more | ||||||
|  |          */ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static class TestClass { | ||||||
|  |         private String str; | ||||||
|  |         private int num; | ||||||
|  |         private Date date; | ||||||
|  | 
 | ||||||
|  |         public TestClass(String str, int num, Date date) { | ||||||
|  |             this.str = str; | ||||||
|  |             this.num = num; | ||||||
|  |             this.date = date; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public String getStr() { | ||||||
|  |             return str; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public int getNum() { | ||||||
|  |             return num; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Date getDate() { | ||||||
|  |             return date; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -231,7 +231,7 @@ class CsDhcp(CsDataBag): | |||||||
|         i = IPAddress(entry['ipv4_address']) |         i = IPAddress(entry['ipv4_address']) | ||||||
|         # Calculate the device |         # Calculate the device | ||||||
|         for v in self.devinfo: |         for v in self.devinfo: | ||||||
|             if i > v['network'].network and i < v['network'].broadcast: |             if i > v['network'].network and v['network'].broadcast and i < v['network'].broadcast: | ||||||
|                 v['dnsmasq'] = True |                 v['dnsmasq'] = True | ||||||
|                 # Virtual Router |                 # Virtual Router | ||||||
|                 v['gateway'] = entry['default_gateway'] |                 v['gateway'] = entry['default_gateway'] | ||||||
|  | |||||||
| @ -48,7 +48,7 @@ public class DateUtil { | |||||||
| 
 | 
 | ||||||
|     public static final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT"); |     public static final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT"); | ||||||
|     public static final String YYYYMMDD_FORMAT = "yyyyMMddHHmmss"; |     public static final String YYYYMMDD_FORMAT = "yyyyMMddHHmmss"; | ||||||
|     private static final String ZONED_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ"; |     public static final String ZONED_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ"; | ||||||
|     private static final DateFormat ZONED_DATETIME_SIMPLE_FORMATTER = new SimpleDateFormat(ZONED_DATETIME_FORMAT); |     private static final DateFormat ZONED_DATETIME_SIMPLE_FORMATTER = new SimpleDateFormat(ZONED_DATETIME_FORMAT); | ||||||
| 
 | 
 | ||||||
|     private static final DateTimeFormatter[] parseFormats = new DateTimeFormatter[]{ |     private static final DateTimeFormatter[] parseFormats = new DateTimeFormatter[]{ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user