diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/TimestampUtil.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/TimestampUtil.java new file mode 100644 index 00000000000..340ec738e8e --- /dev/null +++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/TimestampUtil.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.activemq.artemis.utils; + +import java.time.Instant; +import java.time.ZoneId; + +import static java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME; + +public class TimestampUtil { + + /** + * Formats the given epoch time in milliseconds into an RFC 1123 formatted date-time string. This is useful, for + * example, for providing date-time string for display on the web console. + * + * @param epochMillis the epoch time in milliseconds to be formatted + * @return a string representation of the given epoch time formatted in RFC 1123 format + * @see java.time.format.DateTimeFormatter#RFC_1123_DATE_TIME + * @see RFC 1123 + */ + public static String formatEpochMillis(long epochMillis) { + return RFC_1123_DATE_TIME.format(Instant.ofEpochMilli(epochMillis).atZone(ZoneId.of("UTC"))); + } +} \ No newline at end of file diff --git a/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/TimestampUtilTest.java b/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/TimestampUtilTest.java new file mode 100644 index 00000000000..6850d8cf24d --- /dev/null +++ b/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/TimestampUtilTest.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.activemq.artemis.utils; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TimestampUtilTest { + + @Test + public void testFormatEpochMillis() { + assertEquals("Thu, 1 Jan 1970 00:00:00 GMT", TimestampUtil.formatEpochMillis(0)); + assertEquals("Mon, 17 Nov 2025 17:03:05 GMT", TimestampUtil.formatEpochMillis(1763398985514L)); + } +} diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ConnectionView.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ConnectionView.java index 3a1fc012000..ed4aa832daf 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ConnectionView.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ConnectionView.java @@ -16,7 +16,6 @@ */ package org.apache.activemq.artemis.core.management.impl.view; -import java.util.Date; import java.util.List; import java.util.Objects; import java.util.Set; @@ -31,6 +30,8 @@ import org.apache.activemq.artemis.utils.JsonLoader; import org.apache.activemq.artemis.utils.StringUtil; +import static org.apache.activemq.artemis.utils.TimestampUtil.formatEpochMillis; + public class ConnectionView extends ActiveMQAbstractView { private static final String defaultSortField = ConnectionField.CONNECTION_ID.getName(); @@ -61,7 +62,7 @@ public JsonObjectBuilder toJson(RemotingConnection connection) { .add(ConnectionField.CONNECTION_ID.getName(), toString(connection.getID())) .add(ConnectionField.REMOTE_ADDRESS.getName(), toString(connection.getRemoteAddress())) .add(ConnectionField.USERS.getName(), StringUtil.joinStringList(users, ",")) - .add(ConnectionField.CREATION_TIME.getName(), new Date(connection.getCreationTime()).toString()) + .add(ConnectionField.CREATION_TIME.getName(), formatEpochMillis((connection.getCreationTime()))) .add(ConnectionField.IMPLEMENTATION.getName(), toString(connection.getClass().getSimpleName())) .add(ConnectionField.PROTOCOL.getName(), toString(connection.getProtocolName())) .add(ConnectionField.CLIENT_ID.getName(), toString(connection.getClientID())) @@ -88,7 +89,7 @@ public Object getField(RemotingConnection connection, String fieldName) { } return StringUtil.joinStringList(users, ","); case CREATION_TIME: - return new Date(connection.getCreationTime()); + return connection.getCreationTime(); case IMPLEMENTATION: return connection.getClass().getSimpleName(); case PROTOCOL: diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ConsumerView.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ConsumerView.java index 3768c9568f3..91dd1cc4811 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ConsumerView.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ConsumerView.java @@ -16,8 +16,6 @@ */ package org.apache.activemq.artemis.core.management.impl.view; -import java.util.Date; - import org.apache.activemq.artemis.core.management.impl.ActiveMQServerControlImpl; import org.apache.activemq.artemis.core.management.impl.view.predicate.ConsumerFilterPredicate; import org.apache.activemq.artemis.core.server.ActiveMQServer; @@ -26,6 +24,8 @@ import org.apache.activemq.artemis.json.JsonObjectBuilder; import org.apache.activemq.artemis.utils.JsonLoader; +import static org.apache.activemq.artemis.utils.TimestampUtil.formatEpochMillis; + public class ConsumerView extends ActiveMQAbstractView { public static final String CONSUMER_STATUS_OK = "OK"; @@ -69,15 +69,15 @@ public JsonObjectBuilder toJson(ServerConsumer consumer) { .add(ConsumerField.ADDRESS.getName(), toString(consumer.getQueueAddress())) .add(ConsumerField.LOCAL_ADDRESS.getName(), toString(consumer.getConnectionLocalAddress())) .add(ConsumerField.REMOTE_ADDRESS.getName(), toString(consumer.getConnectionRemoteAddress())) - .add(ConsumerField.CREATION_TIME.getName(), new Date(consumer.getCreationTime()).toString()) + .add(ConsumerField.CREATION_TIME.getName(), formatEpochMillis(consumer.getCreationTime())) .add(ConsumerField.MESSAGES_IN_TRANSIT.getName(), toString(consumer.getMessagesInTransit())) .add(ConsumerField.MESSAGES_IN_TRANSIT_SIZE.getName(), toString(consumer.getMessagesInTransitSize())) .add(ConsumerField.MESSAGES_DELIVERED.getName(), toString(consumer.getMessagesDelivered())) .add(ConsumerField.MESSAGES_DELIVERED_SIZE.getName(), toString(consumer.getMessagesDeliveredSize())) .add(ConsumerField.MESSAGES_ACKNOWLEDGED.getName(), toString(consumer.getMessagesAcknowledged())) .add(ConsumerField.MESSAGES_ACKNOWLEDGED_AWAITING_COMMIT.getName(), toString(consumer.getMessagesAcknowledgedAwaitingCommit())) - .add(ConsumerField.LAST_DELIVERED_TIME.getName(), consumer.getLastDeliveredTime()) - .add(ConsumerField.LAST_ACKNOWLEDGED_TIME.getName(), consumer.getLastAcknowledgedTime()) + .add(ConsumerField.LAST_DELIVERED_TIME.getName(), formatEpochMillis(consumer.getLastDeliveredTime())) + .add(ConsumerField.LAST_ACKNOWLEDGED_TIME.getName(), formatEpochMillis(consumer.getLastAcknowledgedTime())) .add(ConsumerField.STATUS.getName(), ConsumerView.checkConsumerStatus(consumer, server)); return obj; @@ -106,7 +106,7 @@ public Object getField(ServerConsumer consumer, String fieldName) { case FILTER -> consumer.getFilterString(); case LOCAL_ADDRESS -> consumer.getConnectionLocalAddress(); case REMOTE_ADDRESS -> consumer.getConnectionRemoteAddress(); - case CREATION_TIME -> new Date(consumer.getCreationTime()); + case CREATION_TIME -> consumer.getCreationTime(); case MESSAGES_IN_TRANSIT -> consumer.getMessagesInTransit(); case MESSAGES_IN_TRANSIT_SIZE -> consumer.getMessagesInTransitSize(); case MESSAGES_DELIVERED -> consumer.getMessagesDelivered(); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ProducerView.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ProducerView.java index b08e6076f80..588c5044aa3 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ProducerView.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/ProducerView.java @@ -25,6 +25,8 @@ import org.apache.activemq.artemis.json.JsonObjectBuilder; import org.apache.activemq.artemis.utils.JsonLoader; +import static org.apache.activemq.artemis.utils.TimestampUtil.formatEpochMillis; + public class ProducerView extends ActiveMQAbstractView { private static final String defaultSortField = ProducerField.CREATION_TIME.getName(); @@ -62,7 +64,7 @@ public JsonObjectBuilder toJson(ServerProducer producer) { .add(ProducerField.ADDRESS.getName(), toString(Objects.requireNonNullElse(producer.getAddress(), session.getDefaultAddress()))) .add(ProducerField.LOCAL_ADDRESS.getName(), toString(session.getRemotingConnection().getTransportConnection().getLocalAddress())) .add(ProducerField.REMOTE_ADDRESS.getName(), toString(session.getRemotingConnection().getTransportConnection().getRemoteAddress())) - .add(ProducerField.CREATION_TIME.getName(), toString(producer.getCreationTime())) + .add(ProducerField.CREATION_TIME.getName(), formatEpochMillis((producer.getCreationTime()))) .add(ProducerField.MESSAGE_SENT.getName(), producer.getMessagesSent()) .add(ProducerField.MESSAGE_SENT_SIZE.getName(), producer.getMessagesSentSize()) .add(ProducerField.LAST_PRODUCED_MESSAGE_ID.getName(), toString(producer.getLastProducedMessageID())); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/SessionView.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/SessionView.java index c9c5369fcde..9aa09b318b1 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/SessionView.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/SessionView.java @@ -16,14 +16,15 @@ */ package org.apache.activemq.artemis.core.management.impl.view; -import org.apache.activemq.artemis.json.JsonObjectBuilder; -import java.util.Date; import java.util.Objects; import org.apache.activemq.artemis.core.management.impl.view.predicate.SessionFilterPredicate; import org.apache.activemq.artemis.core.server.ServerSession; +import org.apache.activemq.artemis.json.JsonObjectBuilder; import org.apache.activemq.artemis.utils.JsonLoader; +import static org.apache.activemq.artemis.utils.TimestampUtil.formatEpochMillis; + public class SessionView extends ActiveMQAbstractView { private static final String defaultSortField = SessionField.ID.getName(); @@ -44,7 +45,7 @@ public JsonObjectBuilder toJson(ServerSession session) { .add(SessionField.ID.getName(), toString(session.getName())) .add(SessionField.USER.getName(), toString(session.getUsername())) .add(SessionField.VALIDATED_USER.getName(), toString(session.getValidatedUser())) - .add(SessionField.CREATION_TIME.getName(), new Date(session.getCreationTime()).toString()) + .add(SessionField.CREATION_TIME.getName(), formatEpochMillis((session.getCreationTime()))) .add(SessionField.CONSUMER_COUNT.getName(), session.getConsumerCount()) .add(SessionField.PRODUCER_COUNT.getName(), session.getProducerCount()) .add(SessionField.CONNECTION_ID.getName(), session.getConnectionID().toString()) @@ -60,7 +61,7 @@ public Object getField(ServerSession session, String fieldName) { case ID -> session.getName(); case USER -> session.getUsername(); case VALIDATED_USER -> session.getValidatedUser(); - case CREATION_TIME -> new Date(session.getCreationTime()); + case CREATION_TIME -> session.getCreationTime(); case CONSUMER_COUNT -> session.getConsumerCount(); case PRODUCER_COUNT -> session.getProducerCount(); case CONNECTION_ID -> session.getConnectionID();