This is an automated email from the ASF dual-hosted git repository.

sureshanaparti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/main by this push:
     new 9de77e1cc13 API to list console sessions (#11016)
9de77e1cc13 is described below

commit 9de77e1cc137c64b3f5b75f1c759171b8a6e7973
Author: Bernardo De Marco Gonçalves <bernardomg2...@gmail.com>
AuthorDate: Fri Aug 1 11:58:33 2025 -0300

    API to list console sessions (#11016)
    
    * create API to list console sessions
---
 .../org/apache/cloudstack/api/ApiConstants.java    |   3 +
 .../apache/cloudstack/api/ResponseGenerator.java   |   4 +
 .../user/consoleproxy/ListConsoleSessionsCmd.java  | 182 ++++++++++++++++
 .../api/response/ConsoleSessionResponse.java       | 236 +++++++++++++++++++++
 .../consoleproxy/ConsoleAccessManager.java         |   7 +
 .../cloudstack/consoleproxy/ConsoleSession.java    |  32 +--
 .../consoleproxy/ListConsoleSessionsCmdTest.java   | 124 +++++++++++
 .../main/java/com/cloud/vm/ConsoleSessionVO.java   |  25 ++-
 .../java/com/cloud/vm/dao/ConsoleSessionDao.java   |   6 +
 .../com/cloud/vm/dao/ConsoleSessionDaoImpl.java    |  84 +++++++-
 .../resources/META-INF/db/schema-42010to42100.sql  |   9 +
 .../main/java/com/cloud/api/ApiResponseHelper.java |  69 ++++++
 .../com/cloud/server/ManagementServerImpl.java     |   5 +
 .../consoleproxy/ConsoleAccessManagerImpl.java     |  92 +++++++-
 .../java/com/cloud/api/ApiResponseHelperTest.java  | 128 +++++++++++
 .../consoleproxy/ConsoleAccessManagerImplTest.java | 205 ++++++++++++++++++
 tools/apidoc/gen_toc.py                            |   3 +-
 17 files changed, 1192 insertions(+), 22 deletions(-)

diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java 
b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
index 70d3763b0be..f77f8495190 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -23,6 +23,7 @@ public class ApiConstants {
     public static final String ACCOUNT_ID = "accountid";
     public static final String ACCOUNT_IDS = "accountids";
     public static final String ACCUMULATE = "accumulate";
+    public static final String ACQUIRED = "acquired";
     public static final String ACTIVATION_RULE = "activationrule";
     public static final String ACTIVITY = "activity";
     public static final String ADAPTER_TYPE = "adaptertype";
@@ -94,9 +95,11 @@ public class ApiConstants {
     public static final String CONVERT_INSTANCE_HOST_ID = 
"convertinstancehostid";
     public static final String CONVERT_INSTANCE_STORAGE_POOL_ID = 
"convertinstancepoolid";
     public static final String ENABLED_REVOCATION_CHECK = 
"enabledrevocationcheck";
+    public static final String CLIENT_ADDRESS = "clientaddress";
     public static final String COMBINED_CAPACITY_ORDERING = "COMBINED";
     public static final String CONTROLLER = "controller";
     public static final String CONTROLLER_UNIT = "controllerunit";
+    public static final String CONSOLE_ENDPOINT_CREATOR_ADDRESS = 
"consoleendpointcreatoraddress";
     public static final String COPY_IMAGE_TAGS = "copyimagetags";
     public static final String CPU_OVERCOMMIT_RATIO = "cpuOvercommitRatio";
     public static final String CSR = "csr";
diff --git a/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java 
b/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
index 51918570078..8e92e877f5c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
@@ -22,6 +22,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.cloudstack.api.response.ConsoleSessionResponse;
+import org.apache.cloudstack.consoleproxy.ConsoleSession;
 import org.apache.cloudstack.affinity.AffinityGroup;
 import org.apache.cloudstack.affinity.AffinityGroupResponse;
 import org.apache.cloudstack.api.ApiConstants.HostDetails;
@@ -579,4 +581,6 @@ public interface ResponseGenerator {
     void updateTemplateIsoResponsesForIcons(List<TemplateResponse> responses, 
ResourceTag.ResourceObjectType type);
 
     GuiThemeResponse createGuiThemeResponse(GuiThemeJoin guiThemeJoin);
+
+    ConsoleSessionResponse createConsoleSessionResponse(ConsoleSession 
consoleSession, ResponseView responseView);
 }
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/consoleproxy/ListConsoleSessionsCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/consoleproxy/ListConsoleSessionsCmd.java
new file mode 100644
index 00000000000..774cd9d59fe
--- /dev/null
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/consoleproxy/ListConsoleSessionsCmd.java
@@ -0,0 +1,182 @@
+// 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.import org.apache.cloudstack.context.CallContext;
+package org.apache.cloudstack.api.command.user.consoleproxy;
+
+import org.apache.cloudstack.consoleproxy.ConsoleSession;
+
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.user.UserAccount;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.AccountResponse;
+import org.apache.cloudstack.api.response.ConsoleSessionResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.UserResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.consoleproxy.ConsoleAccessManager;
+
+import javax.inject.Inject;
+import java.util.Date;
+
+@APICommand(name = "listConsoleSessions", description = "Lists console 
sessions.", responseObject = ConsoleSessionResponse.class,
+        entityType = {ConsoleSession.class}, since = "4.21.0",
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        authorized = {RoleType.Admin, RoleType.DomainAdmin, 
RoleType.ResourceAdmin, RoleType.User})
+public class ListConsoleSessionsCmd extends BaseListCmd {
+    @Inject
+    private AccountService accountService;
+
+    @Inject
+    private ConsoleAccessManager consoleAccessManager;
+
+    @ACL
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = 
ConsoleSessionResponse.class, description = "The ID of the console session.")
+    private Long id;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, 
entityType = DomainResponse.class, description = "The domain ID of the account 
that created the console endpoint.")
+    private Long domainId;
+
+    @ACL
+    @Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, 
entityType = AccountResponse.class, description = "The ID of the account that 
created the console endpoint.")
+    private Long accountId;
+
+    @ACL
+    @Parameter(name = ApiConstants.USER_ID, type = CommandType.UUID, 
entityType = UserResponse.class, description = "The ID of the user that created 
the console endpoint.")
+    private Long userId;
+
+    @Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, 
entityType = HostResponse.class, authorized = {RoleType.Admin}, description = 
"Lists console sessions from the specified host.")
+    private Long hostId;
+
+    @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, 
description = "Lists console sessions generated from this date onwards. " +
+            ApiConstants.PARAMETER_DESCRIPTION_START_DATE_POSSIBLE_FORMATS)
+    private Date startDate;
+
+    @Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, 
description = "Lists console sessions generated up until this date. " +
+            ApiConstants.PARAMETER_DESCRIPTION_END_DATE_POSSIBLE_FORMATS)
+    private Date endDate;
+
+    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = 
CommandType.UUID, entityType = UserVmResponse.class, description = "The ID of 
the virtual machine.")
+    private Long vmId;
+
+    @Parameter(name = ApiConstants.CONSOLE_ENDPOINT_CREATOR_ADDRESS, type = 
CommandType.STRING, description = "IP address of the creator of the console 
endpoint.")
+    private String consoleEndpointCreatorAddress;
+
+    @Parameter(name = ApiConstants.CLIENT_ADDRESS, type = CommandType.STRING, 
description = "IP address of the client that accessed the console session.")
+    private String clientAddress;
+
+    @Parameter(name = ApiConstants.ACTIVE_ONLY, type = CommandType.BOOLEAN,
+            description = "Lists only active console sessions, defaults to 
true. Active sessions are the ones that have been acquired and have not been 
removed.")
+    private boolean activeOnly = true;
+
+    @Parameter(name = ApiConstants.ACQUIRED, type = CommandType.BOOLEAN,
+        description = "Lists acquired console sessions, defaults to false. 
Acquired console sessions are the ones that have been accessed. " +
+                "The 'activeonly' parameter has precedence over the 'acquired' 
parameter, i.e., when the 'activeonly' parameter is 'true', the 'acquired' 
parameter value will be ignored.")
+    private boolean acquired = false;
+
+    @Parameter(name = ApiConstants.IS_RECURSIVE, type = CommandType.BOOLEAN,
+            description = "Lists console sessions recursively per domain. If 
an account ID is informed, only the account's console sessions will be listed. 
Defaults to false.")
+    private boolean recursive = false;
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public Long getAccountId() {
+        return accountId;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public Long getHostId() {
+        return hostId;
+    }
+
+    public Date getStartDate() {
+        return startDate;
+    }
+
+    public Date getEndDate() {
+        return endDate;
+    }
+
+    public Long getVmId() {
+        return vmId;
+    }
+
+    public String getConsoleEndpointCreatorAddress() {
+        return consoleEndpointCreatorAddress;
+    }
+
+    public String getClientAddress() {
+        return clientAddress;
+    }
+
+    public boolean isActiveOnly() {
+        return activeOnly;
+    }
+
+    public boolean getAcquired() {
+        return acquired;
+    }
+
+    public boolean isRecursive() {
+        return recursive;
+    }
+
+    @Override
+    public void execute() {
+        ListResponse<ConsoleSessionResponse> response = 
consoleAccessManager.listConsoleSessions(this);
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        if (getId() != null) {
+            ConsoleSession consoleSession = 
consoleAccessManager.listConsoleSessionById(getId());
+            if (consoleSession != null) {
+                return consoleSession.getAccountId();
+            }
+        }
+
+        if (getAccountId() != null) {
+            return getAccountId();
+        }
+
+        if (getUserId() != null) {
+            UserAccount userAccount = 
accountService.getUserAccountById(getUserId());
+            if (userAccount != null) {
+                return userAccount.getAccountId();
+            }
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+}
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/response/ConsoleSessionResponse.java
 
b/api/src/main/java/org/apache/cloudstack/api/response/ConsoleSessionResponse.java
new file mode 100644
index 00000000000..85747d7c2a8
--- /dev/null
+++ 
b/api/src/main/java/org/apache/cloudstack/api/response/ConsoleSessionResponse.java
@@ -0,0 +1,236 @@
+// 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.import org.apache.cloudstack.context.CallContext;
+package org.apache.cloudstack.api.response;
+
+import com.google.gson.annotations.SerializedName;
+
+import com.cloud.serializer.Param;
+import org.apache.cloudstack.consoleproxy.ConsoleSession;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+
+import java.util.Date;
+
+@EntityReference(value = ConsoleSession.class)
+public class ConsoleSessionResponse extends BaseResponse {
+
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "ID of the console session.")
+    private String id;
+
+    @SerializedName(ApiConstants.CREATED)
+    @Param(description = "Date when the console session's endpoint was 
created.")
+    private Date created;
+
+    @SerializedName(ApiConstants.DOMAIN)
+    @Param(description = "Domain of the account that created the console 
endpoint.")
+    private String domain;
+
+    @SerializedName(ApiConstants.DOMAIN_PATH)
+    @Param(description = "Domain path of the account that created the console 
endpoint.")
+    private String domainPath;
+
+    @SerializedName(ApiConstants.DOMAIN_ID)
+    @Param(description = "Domain ID of the account that created the console 
endpoint.")
+    private String domainId;
+
+    @SerializedName(ApiConstants.ACCOUNT)
+    @Param(description = "Account that created the console endpoint.")
+    private String account;
+
+    @SerializedName(ApiConstants.ACCOUNT_ID)
+    @Param(description = "ID of the account that created the console 
endpoint.")
+    private String accountId;
+
+    @SerializedName(ApiConstants.USER)
+    @Param(description = "User that created the console endpoint.")
+    private String user;
+
+    @SerializedName(ApiConstants.USER_ID)
+    @Param(description = "ID of the user that created the console endpoint.")
+    private String userId;
+
+    @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID)
+    @Param(description = "ID of the virtual machine.")
+    private String vmId;
+
+    @SerializedName(ApiConstants.VIRTUAL_MACHINE_NAME)
+    @Param(description = "Name of the virtual machine.")
+    private String vmName;
+
+    @SerializedName(ApiConstants.HOST_ID)
+    @Param(description = "ID of the host.")
+    private String hostId;
+
+    @SerializedName(ApiConstants.HOST_NAME)
+    @Param(description = "Name of the host.")
+    private String hostName;
+
+    @SerializedName(ApiConstants.ACQUIRED)
+    @Param(description = "Date when the console session was acquired.")
+    private Date acquired;
+
+    @SerializedName(ApiConstants.REMOVED)
+    @Param(description = "Date when the console session was removed.")
+    private Date removed;
+
+    @SerializedName(ApiConstants.CONSOLE_ENDPOINT_CREATOR_ADDRESS)
+    @Param(description = "IP address of the creator of the console endpoint.")
+    private String consoleEndpointCreatorAddress;
+
+    @SerializedName(ApiConstants.CLIENT_ADDRESS)
+    @Param(description = "IP address of the client that created the console 
session.")
+    private String clientAddress;
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public void setDomainPath(String domainPath) {
+        this.domainPath = domainPath;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    public void setAccount(String account) {
+        this.account = account;
+    }
+
+    public void setAccountId(String accountId) {
+        this.accountId = accountId;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public void setVmId(String vmId) {
+        this.vmId = vmId;
+    }
+
+    public void setVmName(String vmName) {
+        this.vmName = vmName;
+    }
+
+    public void setHostId(String hostId) {
+        this.hostId = hostId;
+    }
+
+    public void setHostName(String hostName) {
+        this.hostName = hostName;
+    }
+
+    public void setAcquired(Date acquired) {
+        this.acquired = acquired;
+    }
+
+    public void setRemoved(Date removed) {
+        this.removed = removed;
+    }
+
+    public void setConsoleEndpointCreatorAddress(String 
consoleEndpointCreatorAddress) {
+        this.consoleEndpointCreatorAddress = consoleEndpointCreatorAddress;
+    }
+
+    public void setClientAddress(String clientAddress) {
+        this.clientAddress = clientAddress;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public String getDomainPath() {
+        return domainPath;
+    }
+
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public String getAccount() {
+        return account;
+    }
+
+    public String getAccountId() {
+        return accountId;
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public String getVmId() {
+        return vmId;
+    }
+
+    public String getVmName() {
+        return vmName;
+    }
+
+    public String getHostId() {
+        return hostId;
+    }
+
+    public String getHostName() {
+        return hostName;
+    }
+
+    public Date getAcquired() {
+        return acquired;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    public String getConsoleEndpointCreatorAddress() {
+        return consoleEndpointCreatorAddress;
+    }
+
+    public String getClientAddress() {
+        return clientAddress;
+    }
+}
diff --git 
a/api/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManager.java
 
b/api/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManager.java
index 23b571e7fae..655b8faf443 100644
--- 
a/api/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManager.java
+++ 
b/api/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManager.java
@@ -18,6 +18,9 @@ package org.apache.cloudstack.consoleproxy;
 
 import com.cloud.utils.component.Manager;
 import org.apache.cloudstack.api.command.user.consoleproxy.ConsoleEndpoint;
+import 
org.apache.cloudstack.api.command.user.consoleproxy.ListConsoleSessionsCmd;
+import org.apache.cloudstack.api.response.ConsoleSessionResponse;
+import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.framework.config.ConfigKey;
 import org.apache.cloudstack.framework.config.Configurable;
 import java.util.Date;
@@ -48,4 +51,8 @@ public interface ConsoleAccessManager extends Manager, 
Configurable {
 
     String genAccessTicket(String host, String port, String sid, String tag, 
String sessionUuid);
     String genAccessTicket(String host, String port, String sid, String tag, 
Date normalizedHashTime, String sessionUuid);
+
+    ListResponse<ConsoleSessionResponse> 
listConsoleSessions(ListConsoleSessionsCmd cmd);
+
+    ConsoleSession listConsoleSessionById(long id);
 }
diff --git 
a/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleSessionDao.java 
b/api/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleSession.java
similarity index 63%
copy from engine/schema/src/main/java/com/cloud/vm/dao/ConsoleSessionDao.java
copy to api/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleSession.java
index 95ced889b3d..6cbdd31fd94 100644
--- a/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleSessionDao.java
+++ b/api/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleSession.java
@@ -1,4 +1,3 @@
-//
 // 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
@@ -15,25 +14,32 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-//
+package org.apache.cloudstack.consoleproxy;
 
-package com.cloud.vm.dao;
-
-import com.cloud.vm.ConsoleSessionVO;
-import com.cloud.utils.db.GenericDao;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
 
 import java.util.Date;
-import java.util.List;
 
-public interface ConsoleSessionDao extends GenericDao<ConsoleSessionVO, Long> {
+public interface ConsoleSession extends InternalIdentity, Identity {
+
+    Date getCreated();
+
+    long getDomainId();
+
+    long getAccountId();
+
+    long getUserId();
+
+    long getInstanceId();
 
-    void removeSession(String sessionUuid);
+    long getHostId();
 
-    boolean isSessionAllowed(String sessionUuid);
+    Date getRemoved();
 
-    int expungeSessionsOlderThanDate(Date date);
+    Date getAcquired();
 
-    void acquireSession(String sessionUuid, String clientAddress);
+    String getConsoleEndpointCreatorAddress();
 
-    int expungeByVmList(List<Long> vmIds, Long batchSize);
+    String getClientAddress();
 }
diff --git 
a/api/src/test/java/org/apache/cloudstack/api/command/user/consoleproxy/ListConsoleSessionsCmdTest.java
 
b/api/src/test/java/org/apache/cloudstack/api/command/user/consoleproxy/ListConsoleSessionsCmdTest.java
new file mode 100644
index 00000000000..47bef14bb61
--- /dev/null
+++ 
b/api/src/test/java/org/apache/cloudstack/api/command/user/consoleproxy/ListConsoleSessionsCmdTest.java
@@ -0,0 +1,124 @@
+// 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.import org.apache.cloudstack.context.CallContext;
+package org.apache.cloudstack.api.command.user.consoleproxy;
+
+import org.apache.cloudstack.consoleproxy.ConsoleSession;
+import com.cloud.user.AccountService;
+
+import com.cloud.user.UserAccount;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.consoleproxy.ConsoleAccessManager;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ListConsoleSessionsCmdTest {
+    @Mock
+    private AccountService accountServiceMock;
+
+    @Mock
+    private ConsoleAccessManager consoleAccessManagerMock;
+
+    @Spy
+    @InjectMocks
+    private ListConsoleSessionsCmd listConsoleSessionsCmdSpy;
+
+    @Test
+    public void executeTestApiExecutionShouldCallServiceLayer() {
+        
Mockito.when(consoleAccessManagerMock.listConsoleSessions(listConsoleSessionsCmdSpy)).thenReturn(new
 ListResponse<>());
+        listConsoleSessionsCmdSpy.execute();
+        
Mockito.verify(consoleAccessManagerMock).listConsoleSessions(listConsoleSessionsCmdSpy);
+    }
+
+    @Test
+    public void getEntityOwnerIdTestReturnConsoleSessionIdIfProvided() {
+        ConsoleSession consoleSessionMock = Mockito.mock(ConsoleSession.class);
+        long consoleSessionId = 2L;
+        long accountId = 2L;
+
+        
Mockito.when(listConsoleSessionsCmdSpy.getId()).thenReturn(consoleSessionId);
+        
Mockito.when(consoleAccessManagerMock.listConsoleSessionById(consoleSessionId)).thenReturn(consoleSessionMock);
+        Mockito.when(consoleSessionMock.getAccountId()).thenReturn(accountId);
+
+        Assert.assertEquals(accountId, 
listConsoleSessionsCmdSpy.getEntityOwnerId());
+    }
+
+    @Test
+    public void 
getEntityOwnerIdTestReturnAccountIdWhenNoConsoleSessionIdIsProvided() {
+        long accountId = 2L;
+
+        Mockito.when(listConsoleSessionsCmdSpy.getId()).thenReturn(null);
+        
Mockito.when(listConsoleSessionsCmdSpy.getAccountId()).thenReturn(accountId);
+
+        Assert.assertEquals(accountId, 
listConsoleSessionsCmdSpy.getEntityOwnerId());
+    }
+
+    @Test
+    public void 
getEntityOwnerIdTestReturnUserIdWhenNoConsoleSessionIdAndAccountIdAreProvided() 
{
+        UserAccount userAccountMock = Mockito.mock(UserAccount.class);
+        long userId = 2L;
+
+        Mockito.when(listConsoleSessionsCmdSpy.getId()).thenReturn(null);
+        
Mockito.when(listConsoleSessionsCmdSpy.getAccountId()).thenReturn(null);
+        Mockito.when(listConsoleSessionsCmdSpy.getUserId()).thenReturn(userId);
+        
Mockito.when(accountServiceMock.getUserAccountById(userId)).thenReturn(userAccountMock);
+        Mockito.when(userAccountMock.getAccountId()).thenReturn(userId);
+
+        Assert.assertEquals(userId, 
listConsoleSessionsCmdSpy.getEntityOwnerId());
+    }
+
+    @Test
+    public void 
getEntityOwnerIdTestReturnSystemAccountIdWhenNoConsoleSessionIdAndAccountIdAndUserIdAreProvided()
 {
+        long systemAccountId = 1L;
+
+        Mockito.when(listConsoleSessionsCmdSpy.getId()).thenReturn(null);
+        
Mockito.when(listConsoleSessionsCmdSpy.getAccountId()).thenReturn(null);
+        Mockito.when(listConsoleSessionsCmdSpy.getUserId()).thenReturn(null);
+
+        Assert.assertEquals(systemAccountId, 
listConsoleSessionsCmdSpy.getEntityOwnerId());
+    }
+
+    @Test
+    public void 
getEntityOwnerIdTestReturnSystemAccountIdWhenConsoleSessionDoesNotExist() {
+        long consoleSessionId = 2L;
+        long systemAccountId = 1L;
+
+        
Mockito.when(listConsoleSessionsCmdSpy.getId()).thenReturn(consoleSessionId);
+        
Mockito.when(consoleAccessManagerMock.listConsoleSessionById(consoleSessionId)).thenReturn(null);
+
+        Assert.assertEquals(systemAccountId, 
listConsoleSessionsCmdSpy.getEntityOwnerId());
+    }
+
+    @Test
+    public void 
getEntityOwnerIdTestReturnSystemAccountIdWhenUserAccountDoesNotExist() {
+        long userId = 2L;
+        long systemAccountId = 1L;
+
+        Mockito.when(listConsoleSessionsCmdSpy.getUserId()).thenReturn(userId);
+        
Mockito.when(accountServiceMock.getUserAccountById(userId)).thenReturn(null);
+
+        Assert.assertEquals(systemAccountId, 
listConsoleSessionsCmdSpy.getEntityOwnerId());
+    }
+}
diff --git a/engine/schema/src/main/java/com/cloud/vm/ConsoleSessionVO.java 
b/engine/schema/src/main/java/com/cloud/vm/ConsoleSessionVO.java
index ef777be2de9..d8f2838dd47 100644
--- a/engine/schema/src/main/java/com/cloud/vm/ConsoleSessionVO.java
+++ b/engine/schema/src/main/java/com/cloud/vm/ConsoleSessionVO.java
@@ -19,6 +19,8 @@
 
 package com.cloud.vm;
 
+import org.apache.cloudstack.consoleproxy.ConsoleSession;
+
 import java.util.Date;
 
 import javax.persistence.Column;
@@ -32,7 +34,7 @@ import javax.persistence.TemporalType;
 
 @Entity
 @Table(name = "console_session")
-public class ConsoleSessionVO {
+public class ConsoleSessionVO implements ConsoleSession {
 
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
@@ -45,6 +47,9 @@ public class ConsoleSessionVO {
     @Column(name = "created")
     private Date created;
 
+    @Column(name = "domain_id")
+    private long domainId;
+
     @Column(name = "account_id")
     private long accountId;
 
@@ -86,6 +91,7 @@ public class ConsoleSessionVO {
         this.uuid = uuid;
     }
 
+    @Override
     public Date getCreated() {
         return created;
     }
@@ -94,6 +100,16 @@ public class ConsoleSessionVO {
         this.created = created;
     }
 
+    @Override
+    public long getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(long domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
     public long getAccountId() {
         return accountId;
     }
@@ -102,6 +118,7 @@ public class ConsoleSessionVO {
         this.accountId = accountId;
     }
 
+    @Override
     public long getUserId() {
         return userId;
     }
@@ -110,6 +127,7 @@ public class ConsoleSessionVO {
         this.userId = userId;
     }
 
+    @Override
     public long getInstanceId() {
         return instanceId;
     }
@@ -118,6 +136,7 @@ public class ConsoleSessionVO {
         this.instanceId = instanceId;
     }
 
+    @Override
     public long getHostId() {
         return hostId;
     }
@@ -126,6 +145,7 @@ public class ConsoleSessionVO {
         this.hostId = hostId;
     }
 
+    @Override
     public Date getRemoved() {
         return removed;
     }
@@ -134,6 +154,7 @@ public class ConsoleSessionVO {
         this.removed = removed;
     }
 
+    @Override
     public Date getAcquired() {
         return acquired;
     }
@@ -142,6 +163,7 @@ public class ConsoleSessionVO {
         this.acquired = acquired;
     }
 
+    @Override
     public String getConsoleEndpointCreatorAddress() {
         return consoleEndpointCreatorAddress;
     }
@@ -150,6 +172,7 @@ public class ConsoleSessionVO {
         this.consoleEndpointCreatorAddress = consoleEndpointCreatorAddress;
     }
 
+    @Override
     public String getClientAddress() {
         return clientAddress;
     }
diff --git 
a/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleSessionDao.java 
b/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleSessionDao.java
index 95ced889b3d..b8fb9557a35 100644
--- a/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleSessionDao.java
+++ b/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleSessionDao.java
@@ -19,6 +19,7 @@
 
 package com.cloud.vm.dao;
 
+import com.cloud.utils.Pair;
 import com.cloud.vm.ConsoleSessionVO;
 import com.cloud.utils.db.GenericDao;
 
@@ -36,4 +37,9 @@ public interface ConsoleSessionDao extends 
GenericDao<ConsoleSessionVO, Long> {
     void acquireSession(String sessionUuid, String clientAddress);
 
     int expungeByVmList(List<Long> vmIds, Long batchSize);
+
+    Pair<List<ConsoleSessionVO>, Integer> listConsoleSessions(Long id, 
List<Long> domainIds, Long accountId, Long userId, Long hostId,
+                                                              Date startDate, 
Date endDate, Long instanceId,
+                                                              String 
consoleEndpointCreatorAddress, String clientAddress,
+                                                              boolean 
activeOnly, boolean acquired, Long pageSizeVal, Long startIndex);
 }
diff --git 
a/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleSessionDaoImpl.java 
b/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleSessionDaoImpl.java
index 3d117894670..562142eecc8 100644
--- a/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleSessionDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleSessionDaoImpl.java
@@ -22,6 +22,8 @@ package com.cloud.vm.dao;
 import java.util.Date;
 import java.util.List;
 
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.Filter;
 import org.apache.commons.collections.CollectionUtils;
 
 import com.cloud.utils.db.GenericDaoBase;
@@ -30,13 +32,28 @@ import com.cloud.utils.db.SearchCriteria;
 import com.cloud.vm.ConsoleSessionVO;
 
 public class ConsoleSessionDaoImpl extends GenericDaoBase<ConsoleSessionVO, 
Long> implements ConsoleSessionDao {
+    private static final String ID = "id";
+    private static final String DOMAIN_IDS = "domainIds";
+    private static final String ACCOUNT_ID = "accountId";
+    private static final String USER_ID = "userId";
+    private static final String HOST_ID = "hostId";
+    private static final String INSTANCE_ID = "instanceId";
+    private static final String VM_IDS = "vmIds";
+    private static final String START_DATE = "startDate";
+    private static final String END_DATE = "endDate";
+    private static final String CREATOR_ADDRESS = "creatorAddress";
+    private static final String CLIENT_ADDRESS = "clientAddress";
+    private static final String ACQUIRED = "acquired";
+    private static final String CREATED = "created";
+    private static final String REMOVED = "removed";
+    private static final String REMOVED_NOT_NULL = "removedNotNull";
 
     private final SearchBuilder<ConsoleSessionVO> searchByRemovedDate;
 
     public ConsoleSessionDaoImpl() {
         searchByRemovedDate = createSearchBuilder();
-        searchByRemovedDate.and("removedNotNull", 
searchByRemovedDate.entity().getRemoved(), SearchCriteria.Op.NNULL);
-        searchByRemovedDate.and("removed", 
searchByRemovedDate.entity().getRemoved(), SearchCriteria.Op.LTEQ);
+        searchByRemovedDate.and(REMOVED_NOT_NULL, 
searchByRemovedDate.entity().getRemoved(), SearchCriteria.Op.NNULL);
+        searchByRemovedDate.and(REMOVED, 
searchByRemovedDate.entity().getRemoved(), SearchCriteria.Op.LTEQ);
     }
 
     @Override
@@ -57,7 +74,7 @@ public class ConsoleSessionDaoImpl extends 
GenericDaoBase<ConsoleSessionVO, Long
     @Override
     public int expungeSessionsOlderThanDate(Date date) {
         SearchCriteria<ConsoleSessionVO> searchCriteria = 
searchByRemovedDate.create();
-        searchCriteria.setParameters("removed", date);
+        searchCriteria.setParameters(REMOVED, date);
         return expunge(searchCriteria);
     }
 
@@ -75,9 +92,66 @@ public class ConsoleSessionDaoImpl extends 
GenericDaoBase<ConsoleSessionVO, Long
             return 0;
         }
         SearchBuilder<ConsoleSessionVO> sb = createSearchBuilder();
-        sb.and("vmIds", sb.entity().getInstanceId(), SearchCriteria.Op.IN);
+        sb.and(VM_IDS, sb.entity().getInstanceId(), SearchCriteria.Op.IN);
         SearchCriteria<ConsoleSessionVO> sc = sb.create();
-        sc.setParameters("vmIds", vmIds.toArray());
+        sc.setParameters(VM_IDS, vmIds.toArray());
         return batchExpunge(sc, batchSize);
     }
+
+    @Override
+    public Pair<List<ConsoleSessionVO>, Integer> listConsoleSessions(Long id, 
List<Long> domainIds, Long accountId, Long userId, Long hostId,
+                                                                     Date 
startDate, Date endDate, Long instanceId,
+                                                                     String 
consoleEndpointCreatorAddress, String clientAddress,
+                                                                     boolean 
activeOnly, boolean acquired, Long pageSizeVal, Long startIndex) {
+        Filter filter = new Filter(ConsoleSessionVO.class, CREATED, false, 
startIndex, pageSizeVal);
+        SearchCriteria<ConsoleSessionVO> searchCriteria = 
createListConsoleSessionsSearchCriteria(id, domainIds, accountId, userId, 
hostId,
+                startDate, endDate, instanceId, consoleEndpointCreatorAddress, 
clientAddress, activeOnly, acquired);
+
+        return searchAndCount(searchCriteria, filter, true);
+    }
+
+    private SearchCriteria<ConsoleSessionVO> 
createListConsoleSessionsSearchCriteria(Long id, List<Long> domainIds, Long 
accountId, Long userId, Long hostId,
+                                                                               
      Date startDate, Date endDate, Long instanceId,
+                                                                               
      String consoleEndpointCreatorAddress, String clientAddress,
+                                                                               
      boolean activeOnly, boolean acquired) {
+        SearchCriteria<ConsoleSessionVO> searchCriteria = 
createListConsoleSessionsSearchBuilder(activeOnly, acquired).create();
+
+        searchCriteria.setParametersIfNotNull(ID, id);
+        searchCriteria.setParametersIfNotNull(DOMAIN_IDS, domainIds.toArray());
+        searchCriteria.setParametersIfNotNull(ACCOUNT_ID, accountId);
+        searchCriteria.setParametersIfNotNull(USER_ID, userId);
+        searchCriteria.setParametersIfNotNull(HOST_ID, hostId);
+        searchCriteria.setParametersIfNotNull(INSTANCE_ID, instanceId);
+        searchCriteria.setParametersIfNotNull(START_DATE, startDate);
+        searchCriteria.setParametersIfNotNull(END_DATE, endDate);
+        searchCriteria.setParametersIfNotNull(CREATOR_ADDRESS, 
consoleEndpointCreatorAddress);
+        searchCriteria.setParametersIfNotNull(CLIENT_ADDRESS, clientAddress);
+
+        return searchCriteria;
+    }
+
+    private SearchBuilder<ConsoleSessionVO> 
createListConsoleSessionsSearchBuilder(boolean activeOnly, boolean acquired) {
+        SearchBuilder<ConsoleSessionVO> searchBuilder = createSearchBuilder();
+
+        searchBuilder.and(ID, searchBuilder.entity().getId(), 
SearchCriteria.Op.EQ);
+        searchBuilder.and(DOMAIN_IDS, searchBuilder.entity().getDomainId(), 
SearchCriteria.Op.IN);
+        searchBuilder.and(ACCOUNT_ID, searchBuilder.entity().getAccountId(), 
SearchCriteria.Op.EQ);
+        searchBuilder.and(USER_ID, searchBuilder.entity().getUserId(), 
SearchCriteria.Op.EQ);
+        searchBuilder.and(HOST_ID, searchBuilder.entity().getHostId(), 
SearchCriteria.Op.EQ);
+        searchBuilder.and(INSTANCE_ID, searchBuilder.entity().getInstanceId(), 
SearchCriteria.Op.EQ);
+        searchBuilder.and(START_DATE, searchBuilder.entity().getCreated(), 
SearchCriteria.Op.GTEQ);
+        searchBuilder.and(END_DATE, searchBuilder.entity().getCreated(), 
SearchCriteria.Op.LTEQ);
+        searchBuilder.and(CREATOR_ADDRESS, 
searchBuilder.entity().getConsoleEndpointCreatorAddress(), 
SearchCriteria.Op.EQ);
+        searchBuilder.and(CLIENT_ADDRESS, 
searchBuilder.entity().getClientAddress(), SearchCriteria.Op.EQ);
+
+        if (activeOnly) {
+            searchBuilder.and(ACQUIRED, searchBuilder.entity().getAcquired(), 
SearchCriteria.Op.NNULL);
+            searchBuilder.and(REMOVED, searchBuilder.entity().getRemoved(), 
SearchCriteria.Op.NULL);
+        } else if (acquired) {
+            searchBuilder.and(ACQUIRED, searchBuilder.entity().getAcquired(), 
SearchCriteria.Op.NNULL);
+        }
+
+        searchBuilder.done();
+        return searchBuilder;
+    }
 }
diff --git 
a/engine/schema/src/main/resources/META-INF/db/schema-42010to42100.sql 
b/engine/schema/src/main/resources/META-INF/db/schema-42010to42100.sql
index 4677c8bbd3f..6b2b27f3361 100644
--- a/engine/schema/src/main/resources/META-INF/db/schema-42010to42100.sql
+++ b/engine/schema/src/main/resources/META-INF/db/schema-42010to42100.sql
@@ -745,3 +745,12 @@ JOIN (
     GROUP BY object_store_id
 ) buckets_quota_sum_view ON `object_store`.id = 
buckets_quota_sum_view.object_store_id
 SET `object_store`.allocated_size = buckets_quota_sum_view.total_quota;
+
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.console_session', 'domain_id', 
'bigint(20) unsigned NOT NULL');
+
+UPDATE `cloud`.`console_session` `cs`
+SET `cs`.`domain_id` = (
+    SELECT `acc`.`domain_id`
+    FROM `cloud`.`account` `acc`
+    WHERE `acc`.`id` = `cs`.`account_id`
+);
diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java 
b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
index 41433cb3e6f..7a11a83c180 100644
--- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
@@ -87,6 +87,7 @@ import org.apache.cloudstack.api.response.ConditionResponse;
 import org.apache.cloudstack.api.response.ConfigurationGroupResponse;
 import org.apache.cloudstack.api.response.ConfigurationResponse;
 import org.apache.cloudstack.api.response.ConfigurationSubGroupResponse;
+import org.apache.cloudstack.api.response.ConsoleSessionResponse;
 import org.apache.cloudstack.api.response.ControlledEntityResponse;
 import org.apache.cloudstack.api.response.ControlledViewEntityResponse;
 import org.apache.cloudstack.api.response.CounterResponse;
@@ -205,6 +206,7 @@ import org.apache.cloudstack.backup.dao.BackupRepositoryDao;
 import org.apache.cloudstack.config.Configuration;
 import org.apache.cloudstack.config.ConfigurationGroup;
 import org.apache.cloudstack.config.ConfigurationSubGroup;
+import org.apache.cloudstack.consoleproxy.ConsoleSession;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.direct.download.DirectDownloadCertificate;
 import org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMap;
@@ -5614,4 +5616,71 @@ protected Map<String, ResourceIcon> 
getResourceIconsUsingOsCategory(List<Templat
 
         return guiThemeResponse;
     }
+
+    private void populateDomainFieldsOnConsoleSessionResponse(ConsoleSession 
consoleSession, ConsoleSessionResponse consoleSessionResponse) {
+        Domain domain = 
ApiDBUtils.findDomainById(consoleSession.getDomainId());
+        if (domain != null) {
+            consoleSessionResponse.setDomain(domain.getName());
+            consoleSessionResponse.setDomainPath(domain.getPath());
+            consoleSessionResponse.setDomainId(domain.getUuid());
+        }
+    }
+
+    private void populateUserFieldsOnConsoleSessionResponse(ConsoleSession 
consoleSession, ConsoleSessionResponse consoleSessionResponse) {
+        User user = findUserById(consoleSession.getUserId());
+        if (user != null) {
+            consoleSessionResponse.setUser(user.getUsername());
+            consoleSessionResponse.setUserId(user.getUuid());
+        }
+    }
+
+    private void populateAccountFieldsOnConsoleSessionResponse(ConsoleSession 
consoleSession, ConsoleSessionResponse consoleSessionResponse) {
+        Account account = 
ApiDBUtils.findAccountById(consoleSession.getAccountId());
+        if (account != null) {
+            consoleSessionResponse.setAccount(account.getAccountName());
+            consoleSessionResponse.setAccountId(account.getUuid());
+        }
+    }
+
+    private void populateHostFieldsOnConsoleSessionResponse(ConsoleSession 
consoleSession, ConsoleSessionResponse consoleSessionResponse) {
+        Host host = findHostById(consoleSession.getHostId());
+        if (host != null) {
+            consoleSessionResponse.setHostId(host.getUuid());
+            consoleSessionResponse.setHostName(host.getName());
+        }
+    }
+
+    private void populateInstanceFieldsOnConsoleSessionResponse(ConsoleSession 
consoleSession, ConsoleSessionResponse consoleSessionResponse) {
+        VMInstanceVO instance = 
ApiDBUtils.findVMInstanceById(consoleSession.getInstanceId());
+        if (instance != null) {
+            consoleSessionResponse.setVmId(instance.getUuid());
+            consoleSessionResponse.setVmName(instance.getInstanceName());
+        }
+    }
+
+    @Override
+    public ConsoleSessionResponse createConsoleSessionResponse(ConsoleSession 
consoleSession, ResponseView responseView) {
+        ConsoleSessionResponse consoleSessionResponse = new 
ConsoleSessionResponse();
+        if (consoleSession == null) {
+            return consoleSessionResponse;
+        }
+
+        consoleSessionResponse.setId(consoleSession.getUuid());
+        consoleSessionResponse.setCreated(consoleSession.getCreated());
+        consoleSessionResponse.setAcquired(consoleSession.getAcquired());
+        consoleSessionResponse.setRemoved(consoleSession.getRemoved());
+        
consoleSessionResponse.setConsoleEndpointCreatorAddress(consoleSession.getConsoleEndpointCreatorAddress());
+        
consoleSessionResponse.setClientAddress(consoleSession.getClientAddress());
+
+        populateDomainFieldsOnConsoleSessionResponse(consoleSession, 
consoleSessionResponse);
+        populateUserFieldsOnConsoleSessionResponse(consoleSession, 
consoleSessionResponse);
+        populateAccountFieldsOnConsoleSessionResponse(consoleSession, 
consoleSessionResponse);
+        populateInstanceFieldsOnConsoleSessionResponse(consoleSession, 
consoleSessionResponse);
+        if (responseView == ResponseView.Full) {
+            populateHostFieldsOnConsoleSessionResponse(consoleSession, 
consoleSessionResponse);
+        }
+
+        consoleSessionResponse.setObjectName("consolesession");
+        return consoleSessionResponse;
+    }
 }
diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java 
b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
index 4cd16b42ae9..3245acfbbf2 100644
--- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
@@ -395,6 +395,7 @@ import 
org.apache.cloudstack.api.command.user.bucket.ListBucketsCmd;
 import org.apache.cloudstack.api.command.user.bucket.UpdateBucketCmd;
 import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd;
 import 
org.apache.cloudstack.api.command.user.consoleproxy.CreateConsoleEndpointCmd;
+import 
org.apache.cloudstack.api.command.user.consoleproxy.ListConsoleSessionsCmd;
 import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
 import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd;
 import org.apache.cloudstack.api.command.user.event.ListEventTypesCmd;
@@ -4268,8 +4269,12 @@ public class ManagementServerImpl extends ManagerBase 
implements ManagementServe
         cmdList.add(ConfigureOutOfBandManagementCmd.class);
         cmdList.add(IssueOutOfBandManagementPowerActionCmd.class);
         cmdList.add(ChangeOutOfBandManagementPasswordCmd.class);
+
         cmdList.add(GetUserKeysCmd.class);
+
+        // Console Session APIs
         cmdList.add(CreateConsoleEndpointCmd.class);
+        cmdList.add(ListConsoleSessionsCmd.class);
 
         //user data APIs
         cmdList.add(RegisterUserDataCmd.class);
diff --git 
a/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
 
b/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
index 0ab81a4c1d6..306023a2263 100644
--- 
a/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
+++ 
b/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
@@ -16,6 +16,7 @@
 // under the License.
 package org.apache.cloudstack.consoleproxy;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
@@ -27,7 +28,15 @@ import javax.crypto.spec.SecretKeySpec;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.domain.Domain;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.InvalidParameterValueException;
+import org.apache.cloudstack.api.ResponseGenerator;
+import org.apache.cloudstack.api.ResponseObject;
 import org.apache.cloudstack.api.command.user.consoleproxy.ConsoleEndpoint;
+import 
org.apache.cloudstack.api.command.user.consoleproxy.ListConsoleSessionsCmd;
+import org.apache.cloudstack.api.response.ConsoleSessionResponse;
+import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.security.keys.KeysManager;
 import org.apache.commons.codec.binary.Base64;
@@ -86,6 +95,8 @@ public class ConsoleAccessManagerImpl extends ManagerBase 
implements ConsoleAcce
     @Inject
     private AccountManager accountManager;
     @Inject
+    private DomainDao domainDao;
+    @Inject
     private VirtualMachineManager virtualMachineManager;
     @Inject
     private ManagementServer managementServer;
@@ -103,6 +114,8 @@ public class ConsoleAccessManagerImpl extends ManagerBase 
implements ConsoleAcce
     DataCenterDao dataCenterDao;
     @Inject
     private ConsoleSessionDao consoleSessionDao;
+    @Inject
+    private ResponseGenerator responseGenerator;
 
     private ScheduledExecutorService executorService = null;
 
@@ -181,6 +194,78 @@ public class ConsoleAccessManagerImpl extends ManagerBase 
implements ConsoleAcce
         }
     }
 
+    @Override
+    public ListResponse<ConsoleSessionResponse> 
listConsoleSessions(ListConsoleSessionsCmd cmd) {
+        Pair<List<ConsoleSessionVO>, Integer> consoleSessions = 
listConsoleSessionsInternal(cmd);
+        ListResponse<ConsoleSessionResponse> response = new ListResponse<>();
+
+        ResponseObject.ResponseView responseView = 
ResponseObject.ResponseView.Restricted;
+        Long callerId = CallContext.current().getCallingAccountId();
+        if (accountManager.isRootAdmin(callerId)) {
+            responseView = ResponseObject.ResponseView.Full;
+        }
+
+        List<ConsoleSessionResponse> consoleSessionResponses = new 
ArrayList<>();
+        for (ConsoleSessionVO consoleSession : consoleSessions.first()) {
+            ConsoleSessionResponse consoleSessionResponse = 
responseGenerator.createConsoleSessionResponse(consoleSession, responseView);
+            consoleSessionResponses.add(consoleSessionResponse);
+        }
+
+        response.setResponses(consoleSessionResponses, 
consoleSessions.second());
+        return response;
+    }
+
+    protected Pair<List<ConsoleSessionVO>, Integer> 
listConsoleSessionsInternal(ListConsoleSessionsCmd cmd) {
+        CallContext caller = CallContext.current();
+        long domainId = 
getBaseDomainIdToListConsoleSessions(cmd.getDomainId());
+        Long accountId = cmd.getAccountId();
+        Long userId = cmd.getUserId();
+        boolean isRecursive = cmd.isRecursive();
+
+        boolean isCallerNormalUser = 
accountManager.isNormalUser(caller.getCallingAccountId());
+        if (isCallerNormalUser) {
+            accountId = caller.getCallingAccountId();
+            userId = caller.getCallingUserId();
+        }
+
+        List<Long> domainIds = isRecursive ? 
domainDao.getDomainAndChildrenIds(domainId) : List.of(domainId);
+
+        return consoleSessionDao.listConsoleSessions(cmd.getId(), domainIds, 
accountId, userId,
+                cmd.getHostId(), cmd.getStartDate(), cmd.getEndDate(), 
cmd.getVmId(),
+                cmd.getConsoleEndpointCreatorAddress(), 
cmd.getClientAddress(), cmd.isActiveOnly(),
+                cmd.getAcquired(), cmd.getPageSizeVal(), cmd.getStartIndex());
+    }
+
+    /**
+     * Determines the base domain ID for listing console sessions.
+     *
+     * If no domain ID is provided, returns the caller's domain ID. Otherwise,
+     * checks if the caller has access to that domain and returns the provided 
domain ID.
+     *
+     * @param domainId The domain ID to check, can be null
+     * @return The base domain ID to use for listing console sessions
+     * @throws PermissionDeniedException if the caller does not have access to 
the specified domain
+     */
+    protected long getBaseDomainIdToListConsoleSessions(Long domainId) {
+        Account caller = CallContext.current().getCallingAccount();
+        if (domainId == null) {
+            return caller.getDomainId();
+        }
+
+        Domain domain = domainDao.findById(domainId);
+        if (domain == null) {
+            throw new InvalidParameterValueException(String.format("Unable to 
find domain with ID [%s]. Verify the informed domain and try again.", 
domainId));
+        }
+
+        accountManager.checkAccess(caller, domain);
+        return domainId;
+    }
+
+    @Override
+    public ConsoleSession listConsoleSessionById(long id) {
+        return consoleSessionDao.findByIdIncludingRemoved(id);
+    }
+
     @Override
     public ConsoleEndpoint generateConsoleEndpoint(Long vmId, String 
extraSecurityToken, String clientAddress) {
         try {
@@ -411,10 +496,13 @@ public class ConsoleAccessManagerImpl extends ManagerBase 
implements ConsoleAcce
     }
 
     protected void persistConsoleSession(String sessionUuid, long instanceId, 
long hostId, String consoleEndpointCreatorAddress) {
+        CallContext caller = CallContext.current();
+
         ConsoleSessionVO consoleSessionVo = new ConsoleSessionVO();
         consoleSessionVo.setUuid(sessionUuid);
-        
consoleSessionVo.setAccountId(CallContext.current().getCallingAccountId());
-        consoleSessionVo.setUserId(CallContext.current().getCallingUserId());
+        consoleSessionVo.setDomainId(caller.getCallingAccount().getDomainId());
+        consoleSessionVo.setAccountId(caller.getCallingAccountId());
+        consoleSessionVo.setUserId(caller.getCallingUserId());
         consoleSessionVo.setInstanceId(instanceId);
         consoleSessionVo.setHostId(hostId);
         
consoleSessionVo.setConsoleEndpointCreatorAddress(consoleEndpointCreatorAddress);
diff --git a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java 
b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java
index a5fc791de99..223b0740cf2 100644
--- a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java
+++ b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java
@@ -67,6 +67,7 @@ import org.springframework.test.util.ReflectionTestUtils;
 import com.cloud.capacity.Capacity;
 import com.cloud.configuration.Resource;
 import com.cloud.domain.DomainVO;
+import com.cloud.host.HostVO;
 import com.cloud.network.PublicIpQuarantine;
 import com.cloud.network.as.AutoScaleVmGroup;
 import com.cloud.network.as.AutoScaleVmGroupVO;
@@ -93,7 +94,11 @@ import com.cloud.user.UserDataVO;
 import com.cloud.user.UserVO;
 import com.cloud.user.dao.UserDataDao;
 import com.cloud.utils.net.Ip;
+import com.cloud.vm.ConsoleSessionVO;
 import com.cloud.vm.NicSecondaryIp;
+import com.cloud.vm.VMInstanceVO;
+import org.apache.cloudstack.api.ResponseObject;
+import org.apache.cloudstack.api.response.ConsoleSessionResponse;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ApiResponseHelperTest {
@@ -124,6 +129,19 @@ public class ApiResponseHelperTest {
     @Mock
     ResourceIconManager resourceIconManager;
 
+    @Mock
+    private ConsoleSessionVO consoleSessionMock;
+    @Mock
+    private DomainVO domainVOMock;
+    @Mock
+    private UserVO userVOMock;
+    @Mock
+    private AccountVO accountVOMock;
+    @Mock
+    private HostVO hostVOMock;
+    @Mock
+    private VMInstanceVO vmInstanceVOMock;
+
     @Spy
     @InjectMocks
     ApiResponseHelper apiResponseHelper = new ApiResponseHelper();
@@ -631,4 +649,114 @@ public class ApiResponseHelperTest {
         Mockito.verify(resourceIconManager, 
Mockito.never()).getByResourceTypeAndUuids(Mockito.any(),
                 Mockito.anyCollection());
     }
+
+    private ConsoleSessionResponse 
getExpectedConsoleSessionResponseForTests(boolean fullView) {
+        ConsoleSessionResponse expected = new ConsoleSessionResponse();
+        expected.setId("uuid");
+        expected.setCreated(new Date());
+        expected.setAcquired(new Date());
+        expected.setRemoved(new Date());
+        expected.setConsoleEndpointCreatorAddress("127.0.0.1");
+        expected.setClientAddress("127.0.0.1");
+
+        if (fullView) {
+            expected.setDomain("domain");
+            expected.setDomainPath("domainPath");
+            expected.setDomainId("domainUuid");
+            expected.setUser("user");
+            expected.setUserId("userUuid");
+            expected.setAccount("account");
+            expected.setAccountId("accountUuid");
+            expected.setHostName("host");
+            expected.setHostId("hostUuid");
+            expected.setVmId("vmUuid");
+            expected.setVmName("vmName");
+        }
+
+        return expected;
+    }
+
+    @Test
+    public void 
createConsoleSessionResponseTestShouldReturnRestrictedResponse() {
+        ConsoleSessionResponse expected = 
getExpectedConsoleSessionResponseForTests(false);
+
+        try (MockedStatic<ApiDBUtils> apiDBUtilsStaticMock = 
Mockito.mockStatic(ApiDBUtils.class)) {
+            
Mockito.when(consoleSessionMock.getUuid()).thenReturn(expected.getId());
+            Mockito.when(consoleSessionMock.getDomainId()).thenReturn(2L);
+            
Mockito.when(consoleSessionMock.getCreated()).thenReturn(expected.getCreated());
+            
Mockito.when(consoleSessionMock.getAcquired()).thenReturn(expected.getAcquired());
+            
Mockito.when(consoleSessionMock.getRemoved()).thenReturn(expected.getRemoved());
+            
Mockito.when(consoleSessionMock.getConsoleEndpointCreatorAddress()).thenReturn(expected.getConsoleEndpointCreatorAddress());
+            
Mockito.when(consoleSessionMock.getClientAddress()).thenReturn(expected.getClientAddress());
+
+            ConsoleSessionResponse response = 
apiResponseHelper.createConsoleSessionResponse(consoleSessionMock, 
ResponseObject.ResponseView.Restricted);
+
+            Assert.assertEquals(expected.getId(), response.getId());
+            Assert.assertEquals(expected.getCreated(), response.getCreated());
+            Assert.assertEquals(expected.getAcquired(), 
response.getAcquired());
+            Assert.assertEquals(expected.getRemoved(), response.getRemoved());
+            Assert.assertEquals(expected.getConsoleEndpointCreatorAddress(), 
response.getConsoleEndpointCreatorAddress());
+            Assert.assertEquals(expected.getClientAddress(), 
response.getClientAddress());
+        }
+    }
+
+    @Test
+    public void createConsoleSessionResponseTestShouldReturnFullResponse() {
+        ConsoleSessionResponse expected = 
getExpectedConsoleSessionResponseForTests(true);
+
+        try (MockedStatic<ApiDBUtils> apiDBUtilsStaticMock = 
Mockito.mockStatic(ApiDBUtils.class)) {
+            
Mockito.when(consoleSessionMock.getUuid()).thenReturn(expected.getId());
+            Mockito.when(consoleSessionMock.getDomainId()).thenReturn(2L);
+            Mockito.when(consoleSessionMock.getAccountId()).thenReturn(2L);
+            Mockito.when(consoleSessionMock.getUserId()).thenReturn(2L);
+            Mockito.when(consoleSessionMock.getHostId()).thenReturn(2L);
+            Mockito.when(consoleSessionMock.getInstanceId()).thenReturn(2L);
+            
Mockito.when(consoleSessionMock.getCreated()).thenReturn(expected.getCreated());
+            
Mockito.when(consoleSessionMock.getAcquired()).thenReturn(expected.getAcquired());
+            
Mockito.when(consoleSessionMock.getRemoved()).thenReturn(expected.getRemoved());
+            
Mockito.when(consoleSessionMock.getConsoleEndpointCreatorAddress()).thenReturn(expected.getConsoleEndpointCreatorAddress());
+            
Mockito.when(consoleSessionMock.getClientAddress()).thenReturn(expected.getClientAddress());
+
+            apiDBUtilsStaticMock.when(() -> 
ApiDBUtils.findDomainById(2L)).thenReturn(domainVOMock);
+            
Mockito.when(domainVOMock.getName()).thenReturn(expected.getDomain());
+            
Mockito.when(domainVOMock.getPath()).thenReturn(expected.getDomainPath());
+            
Mockito.when(domainVOMock.getUuid()).thenReturn(expected.getDomainId());
+
+            
Mockito.when(apiResponseHelper.findUserById(2L)).thenReturn(userVOMock);
+            
Mockito.when(userVOMock.getUsername()).thenReturn(expected.getUser());
+            
Mockito.when(userVOMock.getUuid()).thenReturn(expected.getUserId());
+
+            
Mockito.when(ApiDBUtils.findAccountById(2L)).thenReturn(accountVOMock);
+            
Mockito.when(accountVOMock.getAccountName()).thenReturn(expected.getAccount());
+            
Mockito.when(accountVOMock.getUuid()).thenReturn(expected.getAccountId());
+
+            
Mockito.when(apiResponseHelper.findHostById(2L)).thenReturn(hostVOMock);
+            
Mockito.when(hostVOMock.getUuid()).thenReturn(expected.getHostId());
+            
Mockito.when(hostVOMock.getName()).thenReturn(expected.getHostName());
+
+            apiDBUtilsStaticMock.when(() -> 
ApiDBUtils.findVMInstanceById(2L)).thenReturn(vmInstanceVOMock);
+            
Mockito.when(vmInstanceVOMock.getUuid()).thenReturn(expected.getVmId());
+            
Mockito.when(vmInstanceVOMock.getInstanceName()).thenReturn(expected.getVmName());
+
+            ConsoleSessionResponse response = 
apiResponseHelper.createConsoleSessionResponse(consoleSessionMock, 
ResponseObject.ResponseView.Full);
+
+            Assert.assertEquals(expected.getId(), response.getId());
+            Assert.assertEquals(expected.getCreated(), response.getCreated());
+            Assert.assertEquals(expected.getAcquired(), 
response.getAcquired());
+            Assert.assertEquals(expected.getRemoved(), response.getRemoved());
+            Assert.assertEquals(expected.getConsoleEndpointCreatorAddress(), 
response.getConsoleEndpointCreatorAddress());
+            Assert.assertEquals(expected.getClientAddress(), 
response.getClientAddress());
+            Assert.assertEquals(expected.getDomain(), response.getDomain());
+            Assert.assertEquals(expected.getDomainPath(), 
response.getDomainPath());
+            Assert.assertEquals(expected.getDomainId(), 
response.getDomainId());
+            Assert.assertEquals(expected.getUser(), response.getUser());
+            Assert.assertEquals(expected.getUserId(), response.getUserId());
+            Assert.assertEquals(expected.getAccount(), response.getAccount());
+            Assert.assertEquals(expected.getAccountId(), 
response.getAccountId());
+            Assert.assertEquals(expected.getHostId(), response.getHostId());
+            Assert.assertEquals(expected.getHostName(), 
response.getHostName());
+            Assert.assertEquals(expected.getVmId(), response.getVmId());
+            Assert.assertEquals(expected.getVmName(), response.getVmName());
+        }
+    }
 }
diff --git 
a/server/src/test/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImplTest.java
 
b/server/src/test/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImplTest.java
index 748fe19893a..ec7ef20d441 100644
--- 
a/server/src/test/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImplTest.java
+++ 
b/server/src/test/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImplTest.java
@@ -17,21 +17,32 @@
 package org.apache.cloudstack.consoleproxy;
 
 import com.cloud.agent.AgentManager;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
 import com.cloud.exception.PermissionDeniedException;
 import com.cloud.server.ManagementServer;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
+import com.cloud.utils.Pair;
 import com.cloud.utils.db.EntityManager;
+import com.cloud.vm.ConsoleSessionVO;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.dao.ConsoleSessionDao;
 import com.cloud.vm.dao.VMInstanceDetailsDao;
 import org.apache.cloudstack.acl.SecurityChecker;
+import org.apache.cloudstack.api.ResponseGenerator;
+import org.apache.cloudstack.api.ResponseObject;
+import 
org.apache.cloudstack.api.command.user.consoleproxy.ListConsoleSessionsCmd;
+import org.apache.cloudstack.api.response.ConsoleSessionResponse;
+import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.security.keys.KeysManager;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
+import org.mockito.MockedStatic;
 import org.mockito.Mockito;
 import org.mockito.Spy;
 import org.mockito.junit.MockitoJUnitRunner;
@@ -66,6 +77,23 @@ public class ConsoleAccessManagerImplTest {
     @Mock
     Account account;
 
+    @Mock
+    private CallContext callContextMock;
+    @Mock
+    private DomainDao domainDaoMock;
+    @Mock
+    private DomainVO domainMock;
+    @Mock
+    private ConsoleSessionVO consoleSessionMock;
+    @Mock
+    private ConsoleSessionDao consoleSessionDaoMock;
+    @Mock
+    private ConsoleSessionResponse consoleSessionResponseMock;
+    @Mock
+    private ListConsoleSessionsCmd listConsoleSessionsCmdMock;
+    @Mock
+    private ResponseGenerator responseGeneratorMock;
+
     @Test
     public void testCheckSessionPermissionAdminAccount() {
         Mockito.when(account.getId()).thenReturn(1L);
@@ -106,4 +134,181 @@ public class ConsoleAccessManagerImplTest {
             
Assert.assertFalse(consoleAccessManager.checkSessionPermission(virtualMachine, 
account));
         }
     }
+
+    @Test
+    public void 
listConsoleSessionsInternalTestNormalUsersShouldOnlyBeAllowedToListTheirOwnConsoleSessions()
 {
+        long callerDomainId = 5L;
+        long callerAccountId = 5L;
+        long callerUserId = 5L;
+        boolean isRecursive = false;
+
+        try (MockedStatic<CallContext> callContextStaticMock = 
Mockito.mockStatic(CallContext.class)) {
+            
callContextStaticMock.when(CallContext::current).thenReturn(callContextMock);
+            
Mockito.when(listConsoleSessionsCmdMock.getDomainId()).thenReturn(null);
+            
Mockito.when(callContextMock.getCallingAccount()).thenReturn(account);
+            Mockito.when(account.getDomainId()).thenReturn(callerDomainId);
+            
Mockito.when(listConsoleSessionsCmdMock.isRecursive()).thenReturn(isRecursive);
+            
Mockito.when(accountManager.isNormalUser(callerAccountId)).thenReturn(true);
+            
Mockito.when(callContextMock.getCallingAccountId()).thenReturn(callerAccountId);
+            
Mockito.when(callContextMock.getCallingUserId()).thenReturn(callerUserId);
+
+            
consoleAccessManager.listConsoleSessionsInternal(listConsoleSessionsCmdMock);
+        }
+
+        Mockito.verify(consoleSessionDaoMock).listConsoleSessions(
+                Mockito.any(), Mockito.eq(List.of(callerDomainId)), 
Mockito.eq(callerAccountId),
+                Mockito.eq(callerUserId), Mockito.any(), Mockito.any(), 
Mockito.any(), Mockito.any(),
+                Mockito.any(), Mockito.any(), Mockito.anyBoolean(), 
Mockito.anyBoolean(), Mockito.any(), Mockito.any()
+        );
+    }
+
+    @Test
+    public void 
listConsoleSessionsInternalTestAdminsShouldBeAllowedToRetrieveOtherAccountsConsoleSessions()
 {
+        long callerDomainId = 5L;
+        long callerAccountId = 5L;
+        long callerUserId = 5L;
+        boolean isRecursive = false;
+
+        try (MockedStatic<CallContext> callContextStaticMock = 
Mockito.mockStatic(CallContext.class)) {
+            
callContextStaticMock.when(CallContext::current).thenReturn(callContextMock);
+            
Mockito.when(listConsoleSessionsCmdMock.getDomainId()).thenReturn(callerDomainId);
+            
Mockito.doReturn(callerDomainId).when(consoleAccessManager).getBaseDomainIdToListConsoleSessions(callerDomainId);
+            
Mockito.when(listConsoleSessionsCmdMock.getAccountId()).thenReturn(callerAccountId);
+            
Mockito.when(listConsoleSessionsCmdMock.getUserId()).thenReturn(callerUserId);
+            
Mockito.when(listConsoleSessionsCmdMock.isRecursive()).thenReturn(isRecursive);
+            
Mockito.when(callContextMock.getCallingAccountId()).thenReturn(callerAccountId);
+            
Mockito.when(accountManager.isNormalUser(callerAccountId)).thenReturn(false);
+
+            
consoleAccessManager.listConsoleSessionsInternal(listConsoleSessionsCmdMock);
+        }
+
+        Mockito.verify(consoleSessionDaoMock).listConsoleSessions(
+                Mockito.any(), Mockito.eq(List.of(callerDomainId)), 
Mockito.eq(callerAccountId),
+                Mockito.eq(callerUserId), Mockito.any(), Mockito.any(), 
Mockito.any(), Mockito.any(),
+                Mockito.any(), Mockito.any(), Mockito.anyBoolean(), 
Mockito.anyBoolean(), Mockito.any(), Mockito.any()
+        );
+    }
+
+
+    @Test
+    public void 
listConsoleSessionsInternalTestShouldNotFetchConsoleSessionsRecursivelyWhenIsRecursiveIsFalse()
 {
+        long callerDomainId = 5L;
+        long callerAccountId = 5L;
+        long callerUserId = 5L;
+        boolean isRecursive = false;
+
+        try (MockedStatic<CallContext> callContextStaticMock = 
Mockito.mockStatic(CallContext.class)) {
+            
callContextStaticMock.when(CallContext::current).thenReturn(callContextMock);
+            
Mockito.when(listConsoleSessionsCmdMock.getDomainId()).thenReturn(callerDomainId);
+            
Mockito.doReturn(callerDomainId).when(consoleAccessManager).getBaseDomainIdToListConsoleSessions(callerDomainId);
+            
Mockito.when(listConsoleSessionsCmdMock.getAccountId()).thenReturn(callerAccountId);
+            
Mockito.when(listConsoleSessionsCmdMock.getUserId()).thenReturn(callerUserId);
+            
Mockito.when(listConsoleSessionsCmdMock.isRecursive()).thenReturn(isRecursive);
+            
Mockito.when(callContextMock.getCallingAccountId()).thenReturn(callerAccountId);
+            
Mockito.when(accountManager.isNormalUser(callerAccountId)).thenReturn(false);
+
+            
consoleAccessManager.listConsoleSessionsInternal(listConsoleSessionsCmdMock);
+        }
+
+        Mockito.verify(consoleSessionDaoMock).listConsoleSessions(
+                Mockito.any(), Mockito.eq(List.of(callerDomainId)), 
Mockito.eq(callerAccountId),
+                Mockito.eq(callerUserId), Mockito.any(), Mockito.any(), 
Mockito.any(), Mockito.any(),
+                Mockito.any(), Mockito.any(), Mockito.anyBoolean(), 
Mockito.anyBoolean(), Mockito.any(), Mockito.any()
+        );
+    }
+
+    @Test
+    public void 
listConsoleSessionsInternalTestShouldFetchConsoleSessionsRecursivelyWhenIsRecursiveIsTrue()
 {
+        long callerDomainId = 5L;
+        long callerAccountId = 5L;
+        long callerUserId = 5L;
+        boolean isRecursive = true;
+        List<Long> domainIdsCallerHasAccessTo = List.of(callerDomainId, 6L, 
7L);
+
+        try (MockedStatic<CallContext> callContextStaticMock = 
Mockito.mockStatic(CallContext.class)) {
+            
callContextStaticMock.when(CallContext::current).thenReturn(callContextMock);
+            
Mockito.when(listConsoleSessionsCmdMock.getDomainId()).thenReturn(callerDomainId);
+            
Mockito.doReturn(callerDomainId).when(consoleAccessManager).getBaseDomainIdToListConsoleSessions(callerDomainId);
+            
Mockito.when(listConsoleSessionsCmdMock.getAccountId()).thenReturn(callerAccountId);
+            
Mockito.when(listConsoleSessionsCmdMock.getUserId()).thenReturn(callerUserId);
+            
Mockito.when(listConsoleSessionsCmdMock.isRecursive()).thenReturn(isRecursive);
+            
Mockito.when(callContextMock.getCallingAccountId()).thenReturn(callerAccountId);
+            
Mockito.when(accountManager.isNormalUser(callerAccountId)).thenReturn(false);
+            
Mockito.when(domainDaoMock.getDomainAndChildrenIds(callerDomainId)).thenReturn(domainIdsCallerHasAccessTo);
+
+            
consoleAccessManager.listConsoleSessionsInternal(listConsoleSessionsCmdMock);
+        }
+
+        Mockito.verify(consoleSessionDaoMock).listConsoleSessions(
+                Mockito.any(), Mockito.eq(domainIdsCallerHasAccessTo), 
Mockito.eq(callerAccountId),
+                Mockito.eq(callerUserId), Mockito.any(), Mockito.any(), 
Mockito.any(), Mockito.any(),
+                Mockito.any(), Mockito.any(), Mockito.anyBoolean(), 
Mockito.anyBoolean(), Mockito.any(), Mockito.any()
+        );
+    }
+
+    @Test
+    public void 
listConsoleSessionsTestShouldCreateResponsesWithFullViewForRootAdmins() {
+        Mockito.doReturn(new Pair<>(List.of(consoleSessionMock), 1))
+                .when(consoleAccessManager)
+                .listConsoleSessionsInternal(listConsoleSessionsCmdMock);
+
+        try (MockedStatic<CallContext> callContextStaticMock = 
Mockito.mockStatic(CallContext.class)) {
+            
callContextStaticMock.when(CallContext::current).thenReturn(callContextMock);
+            Mockito.when(callContextMock.getCallingAccountId()).thenReturn(2L);
+            Mockito.when(accountManager.isRootAdmin(2L)).thenReturn(true);
+            
Mockito.when(responseGeneratorMock.createConsoleSessionResponse(consoleSessionMock,
 ResponseObject.ResponseView.Full)).thenReturn(consoleSessionResponseMock);
+
+            
consoleAccessManager.listConsoleSessions(listConsoleSessionsCmdMock);
+        }
+        
Mockito.verify(responseGeneratorMock).createConsoleSessionResponse(consoleSessionMock,
 ResponseObject.ResponseView.Full);
+    }
+
+    @Test
+    public void 
listConsoleSessionsTestShouldCreateResponsesWithRestrictedViewForNonRootAdmins()
 {
+        Mockito.doReturn(new Pair<>(List.of(consoleSessionMock), 1))
+                .when(consoleAccessManager)
+                .listConsoleSessionsInternal(listConsoleSessionsCmdMock);
+
+        try (MockedStatic<CallContext> callContextStaticMock = 
Mockito.mockStatic(CallContext.class)) {
+            
callContextStaticMock.when(CallContext::current).thenReturn(callContextMock);
+            Mockito.when(callContextMock.getCallingAccountId()).thenReturn(2L);
+            Mockito.when(accountManager.isRootAdmin(2L)).thenReturn(false);
+            
Mockito.when(responseGeneratorMock.createConsoleSessionResponse(consoleSessionMock,
 
ResponseObject.ResponseView.Restricted)).thenReturn(consoleSessionResponseMock);
+
+            
consoleAccessManager.listConsoleSessions(listConsoleSessionsCmdMock);
+        }
+
+        
Mockito.verify(responseGeneratorMock).createConsoleSessionResponse(consoleSessionMock,
 ResponseObject.ResponseView.Restricted);
+    }
+
+    @Test
+    public void 
getBaseDomainIdToListConsoleSessionsTestIfNoDomainIdIsProvidedReturnCallersDomainId()
 {
+        long callerDomainId = 5L;
+
+        try (MockedStatic<CallContext> callContextStaticMock = 
Mockito.mockStatic(CallContext.class)) {
+            
callContextStaticMock.when(CallContext::current).thenReturn(callContextMock);
+            
Mockito.when(callContextMock.getCallingAccount()).thenReturn(account);
+            Mockito.when(account.getDomainId()).thenReturn(callerDomainId);
+            Assert.assertEquals(callerDomainId, 
consoleAccessManager.getBaseDomainIdToListConsoleSessions(null));
+        }
+    }
+
+    @Test
+    public void 
getBaseDomainIdToListConsoleSessionsTestPerformAccessValidationWhenDomainIsProvided()
 {
+        long domainId = 5L;
+
+        try (MockedStatic<CallContext> callContextStaticMock = 
Mockito.mockStatic(CallContext.class)) {
+            
callContextStaticMock.when(CallContext::current).thenReturn(callContextMock);
+            
Mockito.when(callContextMock.getCallingAccount()).thenReturn(account);
+            
Mockito.when(domainDaoMock.findById(domainId)).thenReturn(domainMock);
+            Assert.assertEquals(domainId, 
consoleAccessManager.getBaseDomainIdToListConsoleSessions(domainId));
+            Mockito.verify(accountManager).checkAccess(account, domainMock);
+        }
+    }
+
+    @Test
+    public void listConsoleSessionByIdTestShouldCallDbLayer() {
+        consoleAccessManager.listConsoleSessionById(1L);
+        Mockito.verify(consoleSessionDaoMock).findByIdIncludingRemoved(1L);
+    }
 }
diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py
index bcaaca2e39a..ad72b4c7938 100644
--- a/tools/apidoc/gen_toc.py
+++ b/tools/apidoc/gen_toc.py
@@ -228,7 +228,8 @@ known_categories = {
     'Rolling': 'Rolling Maintenance',
     'importVsphereStoragePolicies' : 'vSphere storage policies',
     'listVsphereStoragePolicies' : 'vSphere storage policies',
-    'ConsoleEndpoint': 'Console Endpoint',
+    'createConsoleEndpoint': 'Console Session',
+    'listConsoleSessions': 'Console Session',
     'importVm': 'Virtual Machine',
     'revertToVMSnapshot': 'Virtual Machine',
     'listQuarantinedIp': 'IP Quarantine',

Reply via email to