Example #1
0
        internal async Task HandleCloseSessionRequest(CloseSessionParams closeSessionParams, RequestContext <CloseSessionResponse> context)
        {
            Logger.Write(LogLevel.Verbose, "HandleCloseSessionRequest");
            Func <Task <CloseSessionResponse> > closeSession = () =>
            {
                Validate.IsNotNull(nameof(closeSessionParams), closeSessionParams);
                Validate.IsNotNull(nameof(context), context);
                return(Task.Factory.StartNew(() =>
                {
                    string uri = closeSessionParams.SessionId;
                    ObjectExplorerSession session = null;
                    bool success = false;
                    if (!sessionMap.TryGetValue(uri, out session))
                    {
                        Logger.Write(LogLevel.Verbose, $"Cannot close object explorer session. Couldn't find session for uri. {uri} ");
                    }

                    if (session != null)
                    {
                        // refresh the nodes for given node path
                        CloseSession(uri);
                        success = true;
                    }

                    var response = new CloseSessionResponse()
                    {
                        Success = success, SessionId = uri
                    };
                    return response;
                }));
            };

            await HandleRequestAsync(closeSession, context, "HandleCloseSessionRequest");
        }
Example #2
0
        internal async Task HandleExpandRequest(ExpandParams expandParams, RequestContext <bool> context)
        {
            Logger.Write(LogLevel.Verbose, "HandleExpandRequest");

            Func <Task <bool> > expandNode = async() =>
            {
                Validate.IsNotNull(nameof(expandParams), expandParams);
                Validate.IsNotNull(nameof(context), context);

                string uri = expandParams.SessionId;
                ObjectExplorerSession session = null;
                if (!sessionMap.TryGetValue(uri, out session))
                {
                    Logger.Write(LogLevel.Verbose, $"Cannot expand object explorer node. Couldn't find session for uri. {uri} ");
                    await serviceHost.SendEvent(ExpandCompleteNotification.Type, new ExpandResponse
                    {
                        SessionId    = expandParams.SessionId,
                        NodePath     = expandParams.NodePath,
                        ErrorMessage = $"Couldn't find session for session: {uri}"
                    });

                    return(false);
                }
                else
                {
                    RunExpandTask(session, expandParams);
                    return(true);
                }
            };

            await HandleRequestAsync(expandNode, context, "HandleExpandRequest");
        }
 private async Task ExpandTree(NodeInfo node, ObjectExplorerSession session, StringBuilder stringBuilder = null, bool verifySystemObjects = false)
 {
     if (node != null && !node.IsLeaf)
     {
         var children = (await _service.ExpandNode(session, node.NodePath)).Nodes;
         foreach (var child in children)
         {
             VerifyMetadata(child);
             if (stringBuilder != null && child.NodeType != "Folder" && child.NodeType != "FileGroupFile")
             {
                 stringBuilder.Append($"NodeType: {child.NodeType} Label: {child.Label} SubType:{child.NodeSubType} Status:{child.NodeStatus}{Environment.NewLine}");
             }
             if (!verifySystemObjects && (child.Label == SR.SchemaHierarchy_SystemStoredProcedures ||
                                          child.Label == SR.SchemaHierarchy_SystemViews ||
                                          child.Label == SR.SchemaHierarchy_SystemFunctions ||
                                          child.Label == SR.SchemaHierarchy_SystemDataTypes))
             {
                 // don't expand the system folders because then the test will take for ever
             }
             else
             {
                 await ExpandTree(child, session, stringBuilder, verifySystemObjects);
             }
         }
     }
 }
        /// <summary>
        /// Returns the node with the given label
        /// </summary>
        private async Task <NodeInfo> FindNodeByLabel(NodeInfo node, ObjectExplorerSession session, string label)
        {
            if (node != null && node.Label == label)
            {
                return(node);
            }
            else if (node != null && !node.IsLeaf)
            {
                var response = await _service.ExpandNode(session, node.NodePath);

                var children = response.Nodes;
                Assert.NotNull(children);
                foreach (var child in children)
                {
                    VerifyMetadata(child);
                    if (child.Label == label)
                    {
                        return(child);
                    }
                    var result = await FindNodeByLabel(child, session, label);

                    if (result != null)
                    {
                        return(result);
                    }
                }
            }

            return(null);
        }
Example #5
0
 internal async Task <ExpandResponse> ExpandNode(ObjectExplorerSession session, string nodePath, bool forceRefresh = false)
 {
     return(await Task.Factory.StartNew(() =>
     {
         return QueueExpandNodeRequest(session, nodePath, forceRefresh);
     }));
 }
Example #6
0
 private ExpandResponse CreateExpandResponse(ObjectExplorerSession session, ExpandParams expandParams)
 {
     return(new ExpandResponse()
     {
         SessionId = session.Uri, NodePath = expandParams.NodePath
     });
 }
        /// <summary>
        /// Establishes a new session and stores its information
        /// </summary>
        /// <returns><see cref="ObjectExplorerSession"/> object if successful, null if unsuccessful</returns>
        internal async Task <ObjectExplorerSession> DoCreateSession(ConnectionDetails connectionDetails, string uri)
        {
            try
            {
                ObjectExplorerSession session;
                connectionDetails.PersistSecurityInfo = true;
                ConnectParams connectParams = new ConnectParams()
                {
                    OwnerUri = uri, Connection = connectionDetails
                };

                ConnectionCompleteParams connectionResult = await Connect(connectParams, uri);

                if (connectionResult == null)
                {
                    // Connection failed and notification is already sent
                    return(null);
                }

                session = ObjectExplorerSession.CreateSession(connectionResult, serviceProvider);
                sessionMap.AddOrUpdate(uri, session, (key, oldSession) => session);
                return(session);
            }
            catch (Exception ex)
            {
                await SendSessionFailedNotification(uri, ex.Message);

                return(null);
            }
        }
Example #8
0
        internal async Task HandleRefreshRequest(RefreshParams refreshParams, RequestContext <bool> context)
        {
            try
            {
                Logger.Write(LogLevel.Verbose, "HandleRefreshRequest");
                Validate.IsNotNull(nameof(refreshParams), refreshParams);
                Validate.IsNotNull(nameof(context), context);

                string uri = refreshParams.SessionId;
                ObjectExplorerSession session = null;
                if (!sessionMap.TryGetValue(uri, out session))
                {
                    Logger.Write(LogLevel.Verbose, $"Cannot expand object explorer node. Couldn't find session for uri. {uri} ");
                    await serviceHost.SendEvent(ExpandCompleteNotification.Type, new ExpandResponse
                    {
                        SessionId    = refreshParams.SessionId,
                        NodePath     = refreshParams.NodePath,
                        ErrorMessage = $"Couldn't find session for session: {uri}"
                    });
                }
                else
                {
                    RunExpandTask(session, refreshParams, true);
                }
                await context.SendResult(true);
            }
            catch (Exception ex)
            {
                await context.SendError(ex.ToString());
            }
        }
Example #9
0
        /// <summary>
        /// Establishes a new session and stores its information
        /// </summary>
        /// <returns><see cref="ObjectExplorerSession"/> object if successful, null if unsuccessful</returns>
        internal async Task <ObjectExplorerSession> DoCreateSession(ConnectionDetails connectionDetails, string uri)
        {
            try
            {
                ObjectExplorerSession session = null;
                connectionDetails.PersistSecurityInfo = true;
                ConnectParams connectParams = new ConnectParams()
                {
                    OwnerUri = uri, Connection = connectionDetails, Type = Connection.ConnectionType.ObjectExplorer
                };
                bool isDefaultOrSystemDatabase = DatabaseUtils.IsSystemDatabaseConnection(connectionDetails.DatabaseName) || string.IsNullOrWhiteSpace(connectionDetails.DatabaseDisplayName);

                ConnectionInfo           connectionInfo;
                ConnectionCompleteParams connectionResult = await Connect(connectParams, uri);

                if (!connectionService.TryFindConnection(uri, out connectionInfo))
                {
                    return(null);
                }

                if (connectionResult == null)
                {
                    // Connection failed and notification is already sent
                    return(null);
                }

                int       timeout   = (int)TimeSpan.FromSeconds(settings?.CreateSessionTimeout ?? ObjectExplorerSettings.DefaultCreateSessionTimeout).TotalMilliseconds;
                QueueItem queueItem = bindingQueue.QueueBindingOperation(
                    key: bindingQueue.AddConnectionContext(connectionInfo, connectionName),
                    bindingTimeout: timeout,
                    waitForLockTimeout: timeout,
                    bindOperation: (bindingContext, cancelToken) =>
                {
                    session = ObjectExplorerSession.CreateSession(connectionResult, serviceProvider, bindingContext.ServerConnection, isDefaultOrSystemDatabase);
                    session.ConnectionInfo = connectionInfo;

                    sessionMap.AddOrUpdate(uri, session, (key, oldSession) => session);
                    return(session);
                });

                queueItem.ItemProcessed.WaitOne();
                if (queueItem.GetResultAsT <ObjectExplorerSession>() != null)
                {
                    session = queueItem.GetResultAsT <ObjectExplorerSession>();
                }
                return(session);
            }
            catch (Exception ex)
            {
                await SendSessionFailedNotification(uri, ex.Message);

                return(null);
            }
        }
Example #10
0
            public static ObjectExplorerSession CreateSession(ConnectionCompleteParams response, IMultiServiceProvider serviceProvider, ServerConnection serverConnection, bool isDefaultOrSystemDatabase)
            {
                ServerNode rootNode = new ServerNode(response, serviceProvider, serverConnection);
                var        session  = new ObjectExplorerSession(response.OwnerUri, rootNode, serviceProvider, serviceProvider.GetService <ConnectionService>());

                if (!isDefaultOrSystemDatabase)
                {
                    // Assuming the databases are in a folder under server node
                    DatabaseTreeNode databaseNode = new DatabaseTreeNode(rootNode, response.ConnectionSummary.DatabaseName);
                    session.Root = databaseNode;
                }

                return(session);
            }
Example #11
0
        private async Task ExpandNodeAsync(ObjectExplorerSession session, ExpandParams expandParams, CancellationToken cancellationToken, bool forceRefresh = false)
        {
            ExpandResponse response = null;

            response = await ExpandNode(session, expandParams.NodePath, forceRefresh);

            if (cancellationToken.IsCancellationRequested)
            {
                Logger.Write(LogLevel.Verbose, "OE expand canceled");
            }
            else
            {
                await serviceHost.SendEvent(ExpandCompleteNotification.Type, response);
            }
        }
        internal ExpandResponse QueueExpandNodeRequest(ObjectExplorerSession session, string nodePath, bool forceRefresh = false)
        {
            NodeInfo[]     nodes    = null;
            TreeNode       node     = session.Root.FindNodeByPath(nodePath);
            ExpandResponse response = new ExpandResponse {
                Nodes = new NodeInfo[] { }, ErrorMessage = node.ErrorMessage, SessionId = session.Uri, NodePath = nodePath
            };

            if (node != null && Monitor.TryEnter(node.BuildingMetadataLock, LanguageService.OnConnectionWaitTimeout))
            {
                try
                {
                    int       timeout   = (int)TimeSpan.FromSeconds(settings?.ExpandTimeout ?? ObjectExplorerSettings.DefaultExpandTimeout).TotalMilliseconds;
                    QueueItem queueItem = bindingQueue.QueueBindingOperation(
                        key: bindingQueue.AddConnectionContext(session.ConnectionInfo, connectionName),
                        bindingTimeout: timeout,
                        waitForLockTimeout: timeout,
                        bindOperation: (bindingContext, cancelToken) =>
                    {
                        if (forceRefresh)
                        {
                            nodes = node.Refresh().Select(x => x.ToNodeInfo()).ToArray();
                        }
                        else
                        {
                            nodes = node.Expand().Select(x => x.ToNodeInfo()).ToArray();
                        }
                        response.Nodes        = nodes;
                        response.ErrorMessage = node.ErrorMessage;
                        return(response);
                    });

                    queueItem.ItemProcessed.WaitOne();
                    if (queueItem.GetResultAsT <ExpandResponse>() != null)
                    {
                        response = queueItem.GetResultAsT <ExpandResponse>();
                    }
                }
                catch
                {
                }
                finally
                {
                    Monitor.Exit(node.BuildingMetadataLock);
                }
            }
            return(response);
        }
Example #13
0
        private void RunExpandTask(ObjectExplorerSession session, ExpandParams expandParams, bool forceRefresh = false)
        {
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            Task task = ExpandNodeAsync(session, expandParams, cancellationTokenSource.Token, forceRefresh);

            ExpandTask = task;
            Task.Run(async() =>
            {
                ObjectExplorerTaskResult result = await RunTaskWithTimeout(task,
                                                                           settings?.ExpandTimeout ?? ObjectExplorerSettings.DefaultExpandTimeout);

                if (result != null && !result.IsCompleted)
                {
                    cancellationTokenSource.Cancel();
                    ExpandResponse response = CreateExpandResponse(session, expandParams);
                    response.ErrorMessage   = result.Exception != null ? result.Exception.Message: $"Failed to expand node: {expandParams.NodePath} in session {session.Uri}";
                    await serviceHost.SendEvent(ExpandCompleteNotification.Type, response);
                }
                return(result);
            }).ContinueWithOnFaulted(null);
        }
        private async Task ExpandAndVerifyDatabaseNode(string databaseName, ObjectExplorerSession session)
        {
            Assert.NotNull(session);
            Assert.NotNull(session.Root);
            NodeInfo nodeInfo = session.Root.ToNodeInfo();

            Assert.Equal(nodeInfo.IsLeaf, false);
            Assert.Equal(nodeInfo.NodeType, NodeTypes.Database.ToString());
            Assert.True(nodeInfo.Label.Contains(databaseName));
            var children = (await _service.ExpandNode(session, session.Root.GetNodePath())).Nodes;

            //All server children should be folder nodes
            foreach (var item in children)
            {
                Assert.Equal(item.NodeType, "Folder");
            }

            var tablesRoot = children.FirstOrDefault(x => x.Label == SR.SchemaHierarchy_Tables);

            Assert.NotNull(tablesRoot);
        }
 internal async Task <ExpandResponse> ExpandNode(ObjectExplorerSession session, string nodePath, bool forceRefresh = false)
 {
     return(await Task.Factory.StartNew(() =>
     {
         NodeInfo[] nodes = null;
         TreeNode node = session.Root.FindNodeByPath(nodePath);
         if (node != null)
         {
             if (forceRefresh)
             {
                 nodes = node.Refresh().Select(x => x.ToNodeInfo()).ToArray();
             }
             else
             {
                 nodes = node.Expand().Select(x => x.ToNodeInfo()).ToArray();
             }
         }
         return new ExpandResponse {
             Nodes = nodes, ErrorMessage = node.ErrorMessage, SessionId = session.Uri, NodePath = nodePath
         };
     }));
 }
        private async Task VerifyRefresh(ObjectExplorerSession session, string tablePath, string tableName, bool deleted = true)
        {
            //Refresh Root
            var rootChildren = await _service.ExpandNode(session, session.Root.ToNodeInfo().NodePath, true);

            //Verify tables cache is empty
            var rootChildrenCache = session.Root.GetChildren();
            var tablesCache       = rootChildrenCache.First(x => x.Label == SR.SchemaHierarchy_Tables).GetChildren();

            Assert.False(tablesCache.Any());

            //Expand Tables
            var tableChildren = (await _service.ExpandNode(session, tablePath, true)).Nodes;

            //Verify table is not returned
            Assert.Equal(tableChildren.Any(t => t.Label == tableName), !deleted);

            //Verify tables cache has items
            rootChildrenCache = session.Root.GetChildren();
            tablesCache       = rootChildrenCache.First(x => x.Label == SR.SchemaHierarchy_Tables).GetChildren();
            Assert.True(tablesCache.Any());
        }
        private async Task <NodeInfo> ExpandServerNodeAndVerifyDatabaseHierachy(string databaseName, ObjectExplorerSession session, bool serverNode = true)
        {
            Assert.NotNull(session);
            Assert.NotNull(session.Root);
            NodeInfo nodeInfo = session.Root.ToNodeInfo();

            Assert.Equal(nodeInfo.IsLeaf, false);

            NodeInfo databaseNode = null;

            if (serverNode)
            {
                Assert.Equal(nodeInfo.NodeType, NodeTypes.Server.ToString());
                var children = session.Root.Expand(new CancellationToken());

                //All server children should be folder nodes
                foreach (var item in children)
                {
                    Assert.Equal(item.NodeType, "Folder");
                }

                var databasesRoot     = children.FirstOrDefault(x => x.NodeTypeId == NodeTypes.Databases);
                var databasesChildren = (await _service.ExpandNode(session, databasesRoot.GetNodePath())).Nodes;
                var databases         = databasesChildren.Where(x => x.NodeType == NodeTypes.Database.ToString());

                //Verify the test databases is in the list
                Assert.NotNull(databases);
                Assert.False(databases.Any(x => x.Label == "master"));
                var systemDatabasesNode = databasesChildren.FirstOrDefault(x => x.Label == SR.SchemaHierarchy_SystemDatabases);
                Assert.NotNull(systemDatabasesNode);

                var systemDatabases = await _service.ExpandNode(session, systemDatabasesNode.NodePath);

                Assert.True(systemDatabases.Nodes.Any(x => x.Label == "master"));

                databaseNode = databases.FirstOrDefault(d => d.Label == databaseName);
            }
            else
            {
                Assert.Equal(nodeInfo.NodeType, NodeTypes.Database.ToString());
                databaseNode = session.Root.ToNodeInfo();
                Assert.True(databaseNode.Label.Contains(databaseName));
                var databasesChildren = (await _service.ExpandNode(session, databaseNode.NodePath)).Nodes;
                Assert.False(databasesChildren.Any(x => x.Label == SR.SchemaHierarchy_SystemDatabases));
            }
            Assert.NotNull(databaseNode);
            return(databaseNode);
        }
Example #18
0
        internal ExpandResponse QueueExpandNodeRequest(ObjectExplorerSession session, string nodePath, bool forceRefresh = false)
        {
            NodeInfo[]     nodes    = null;
            TreeNode       node     = session.Root.FindNodeByPath(nodePath);
            ExpandResponse response = new ExpandResponse {
                Nodes = new NodeInfo[] { }, ErrorMessage = node.ErrorMessage, SessionId = session.Uri, NodePath = nodePath
            };

            if (node != null && Monitor.TryEnter(node.BuildingMetadataLock, LanguageService.OnConnectionWaitTimeout))
            {
                try
                {
                    int       timeout   = (int)TimeSpan.FromSeconds(settings?.ExpandTimeout ?? ObjectExplorerSettings.DefaultExpandTimeout).TotalMilliseconds;
                    QueueItem queueItem = bindingQueue.QueueBindingOperation(
                        key: bindingQueue.AddConnectionContext(session.ConnectionInfo, connectionName),
                        bindingTimeout: timeout,
                        waitForLockTimeout: timeout,
                        bindOperation: (bindingContext, cancelToken) =>
                    {
                        if (forceRefresh)
                        {
                            nodes = node.Refresh().Select(x => x.ToNodeInfo()).ToArray();
                        }
                        else
                        {
                            nodes = node.Expand().Select(x => x.ToNodeInfo()).ToArray();
                        }
                        response.Nodes        = nodes;
                        response.ErrorMessage = node.ErrorMessage;
                        try
                        {
                            // SMO changes the database when getting sql objects. Make sure the database is changed back to the original one
                            if (bindingContext.ServerConnection.CurrentDatabase != bindingContext.ServerConnection.DatabaseName)
                            {
                                bindingContext.ServerConnection.SqlConnectionObject.ChangeDatabase(bindingContext.ServerConnection.DatabaseName);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Write(LogLevel.Warning, $"Failed to change the database in OE connection. error: {ex.Message}");
                            // We should just try to change the connection. If it fails, there's not much we can do
                        }
                        return(response);
                    });

                    queueItem.ItemProcessed.WaitOne();
                    if (queueItem.GetResultAsT <ExpandResponse>() != null)
                    {
                        response = queueItem.GetResultAsT <ExpandResponse>();
                    }
                }
                catch
                {
                }
                finally
                {
                    Monitor.Exit(node.BuildingMetadataLock);
                }
            }
            return(response);
        }