Skip to content

Commit

Permalink
Fixes #1206
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdriscoll committed Oct 1, 2019
1 parent d978146 commit 61b0578
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 89 deletions.
70 changes: 33 additions & 37 deletions src/UniversalDashboard.UITest/Integration/Scoping.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,32 @@ Get-UDDashboard | Stop-UDDashboard

$Global:MyVariable = "Test"

$Server = Start-UDDashboard -Port 10001 -Dashboard (New-UDDashboard -Title "Test" -Content {})
$Driver = Start-SeFirefox

Describe "Variable Scoping" {

Context "Variable set for session variable" {
$Dashboard = New-UDDashboard -Title "Test" -Content {
New-UDElement -Tag "div" -Endpoint {
$Session:SessionId = $SessionID

New-UDElement -Tag 'div' -Id "output" -Endpoint {
$Session:SessionId
}
}
}

$Server.DashboardService.SetDashboard($Dashboard)
Enter-SeUrl -Driver $Driver -Url "http://localhost:$BrowserPort"

Start-sleep 2

It "should read session id from session variable" {
(Find-SeElement -Id 'output' -Driver $Driver).Text | should not be ""
}
}

Context "Invoke-Command test" {
$Dashboard = New-UDDashboard -Title "Test" -Content {
New-UDButton -Text 'Patch' -Id 'button' -OnClick (
Expand All @@ -26,18 +51,13 @@ Describe "Variable Scoping" {
}
}

$Server = Start-UDDashboard -Port 10001 -Dashboard $Dashboard
$Driver = Start-SeFirefox
$Server.DashboardService.SetDashboard($Dashboard)
Enter-SeUrl -Driver $Driver -Url "http://localhost:$BrowserPort"
Start-Sleep 2

It "should start processes with click" {
Find-SeElement -Id "button" -Driver $Driver | Invoke-SeClick
(Find-SeElement -Id 'child' -Driver $Driver).Text | should be "child"
}

Stop-SeDriver $Driver
Stop-UDDashboard $Server
}

Context "Variable set global" {
Expand All @@ -47,13 +67,11 @@ Describe "Variable Scoping" {
}
}

$Server = Start-UDDashboard -Port 10001 -Dashboard $Dashboard
$Server.DashboardService.SetDashboard($Dashboard)

It "should return global variable" {
(Invoke-RestMethod http://localhost:10001/api/internal/component/element/element) | should be "Test"
}

Stop-UDDashboard $Server
}

Context "Variable set local variable" {
Expand All @@ -66,13 +84,11 @@ Describe "Variable Scoping" {
}
}

$Server = Start-UDDashboard -Port 10001 -Dashboard $Dashboard
$Server.DashboardService.SetDashboard($Dashboard)

It "should return local variable" {
(Invoke-RestMethod http://localhost:10001/api/internal/component/element/element) | should be "localVariable"
}

Stop-UDDashboard $Server
}

Context "Variable set loop variable" {
Expand All @@ -85,16 +101,14 @@ Describe "Variable Scoping" {
}
}

$Server = Start-UDDashboard -Port 10001 -Dashboard $Dashboard
$Server.DashboardService.SetDashboard($Dashboard)

It "should return loop variable" {
1..5 | ForEach-Object {
(Invoke-RestMethod "http://localhost:10001/api/internal/component/element/element$_") | should be $_
}

}

Stop-UDDashboard $Server
}

Context "Variable set for process" {
Expand All @@ -115,10 +129,8 @@ Describe "Variable Scoping" {
}
}

$Server = Start-UDDashboard -Port 10001 -Dashboard $Dashboard
$Driver = Start-SeFirefox
$Server.DashboardService.SetDashboard($Dashboard)
Enter-SeUrl -Driver $Driver -Url "http://localhost:$BrowserPort"
Start-Sleep 2

It "should stop processes with click" {
Get-Process Notepad* | % {
Expand All @@ -138,24 +150,8 @@ Describe "Variable Scoping" {

(Get-Process Notepad* | Measure-Object).Count | Should be 0
}

Stop-SeDriver $Driver
Stop-UDDashboard $Server
}

Context "Variable set for session variable" {
$Dashboard = New-UDDashboard -Title "Test" -Content {
New-UDElement -Tag "div" -Endpoint {
$Session:Variables = @("1", "2,", "3")
}
New-UDElement -Tag 'div' -Id "output"

foreach($Variable in $Session:Variables) {
New-UDButton -Text "ClickMe" -Id "btnClick$Variable" -OnClick {
Set-UDElement -Id "output" -Content { $Varible }
}
}
}
}
}

}
Stop-SeDriver $Driver
Stop-UDDashboard -Server $Server
11 changes: 6 additions & 5 deletions src/UniversalDashboard/Controllers/ComponentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ public class ComponentController : Controller
private static readonly Logger Log = LogManager.GetLogger(nameof(ComponentController));
private readonly IExecutionService _executionService;
private readonly IDashboardService _dashboardService;
private readonly AutoReloader _autoReloader;
private readonly IMemoryCache _memoryCache;
private readonly StateRequestService _stateRequestService;
private readonly ConnectionManager _connectionManager;

public ComponentController(IExecutionService executionService, IDashboardService dashboardService, IMemoryCache memoryCache, AutoReloader autoReloader, StateRequestService stateRequestService)
public ComponentController(IExecutionService executionService, IDashboardService dashboardService, IMemoryCache memoryCache, StateRequestService stateRequestService, ConnectionManager connectionManager)
{
_executionService = executionService;
_dashboardService = dashboardService;
_autoReloader = autoReloader;
_memoryCache = memoryCache;
_stateRequestService = stateRequestService;
_connectionManager = connectionManager;
}

private async Task<IActionResult> RunScript(Endpoint endpoint, Dictionary<string, object> parameters = null, bool noSerialization = false)
Expand All @@ -51,7 +51,8 @@ private async Task<IActionResult> RunScript(Endpoint endpoint, Dictionary<string
{"Request", Request},
{"Response", Response},
{"User", HttpContext?.User?.Identity?.Name},
{"MemoryCache", _memoryCache}
{"MemoryCache", _memoryCache},
{"UDConnectionManager", _connectionManager }
};

try
Expand All @@ -75,7 +76,7 @@ private async Task<IActionResult> RunScript(Endpoint endpoint, Dictionary<string

if (HttpContext.Request.Headers.TryGetValue("UDConnectionId", out StringValues connectionId))
{
executionContext.SessionId = _memoryCache.Get(connectionId) as string;
executionContext.SessionId = _connectionManager.GetSessionId(connectionId);
executionContext.ConnectionId = connectionId;
}

Expand Down
128 changes: 93 additions & 35 deletions src/UniversalDashboard/Execution/SessionDriveProvider.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using Dbg = System.Management.Automation;
using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Provider;
using Microsoft.PowerShell.Commands;
using Microsoft.Extensions.Caching.Memory;
using System.IO;
using NLog;

namespace UniversalDashboard.Execution
{
/// <summary>
/// This provider is the data accessor for shell variables. It uses
/// the HashtableProvider as the base class to get a hashtable as
/// a data store.
/// This is the session scope driver provider.null
/// </summary>
[CmdletProvider("Session", ProviderCapabilities.ShouldProcess)]
[OutputType(typeof(PSVariable), ProviderCmdlet = ProviderCmdlet.SetItem)]
Expand All @@ -27,22 +19,8 @@ namespace UniversalDashboard.Execution
[OutputType(typeof(PSVariable), ProviderCmdlet = ProviderCmdlet.NewItem)]
public sealed class SessionDriveVariableProvider : ContainerCmdletProvider, IContentCmdletProvider
{
private readonly IMemoryCache _memoryCache;
private static readonly Logger Logger = LogManager.GetLogger(nameof(SessionDriveVariableProvider));

#region Constructor

/// <summary>
/// The constructor for the provider that exposes variables to the user
/// as drives.
/// </summary>
public SessionDriveVariableProvider()
{
_memoryCache = ExecutionService.MemoryCache;
} // constructor

#endregion Constructor

#region DriveCmdletProvider overrides

/// <summary>
Expand All @@ -68,7 +46,7 @@ protected override Collection<PSDriveInfo> InitializeDefaultDrives()
return drives;
} // InitializeDefaultDrives

private string ConnectionId
private string SessionId
{
get
{
Expand All @@ -78,26 +56,39 @@ private string ConnectionId

protected override void GetItem(string name)
{
var item = _memoryCache.Get(ConnectionId + name.ToLower());
if (item != null)
if (EndpointService.Instance.Sessions.ContainsKey(SessionId))
{
base.WriteItemObject(item, name.ToLower(), false);
var value = EndpointService.Instance.Sessions[SessionId].GetVariableValue(name);
if (value != null)
{
base.WriteItemObject(value, name.ToLower(), false);
}
}
}

protected override void NewItem(string path, string itemTypeName, object newItemValue)
{
_memoryCache.Set(ConnectionId + path.ToLower(), newItemValue);
if (EndpointService.Instance.Sessions.ContainsKey(SessionId))
{
EndpointService.Instance.Sessions[SessionId].SetVariable(path, newItemValue);
}
}

protected override void SetItem(string name, object value)
{
_memoryCache.Set(ConnectionId + name.ToLower(), value);
if (EndpointService.Instance.Sessions.ContainsKey(SessionId))
{
EndpointService.Instance.Sessions[SessionId].SetVariable(name, value);
}
}

protected override bool ItemExists(string path)
{
return _memoryCache.TryGetValue(ConnectionId + path.ToLower(), out object val);
if (EndpointService.Instance.Sessions.ContainsKey(SessionId))
{
return EndpointService.Instance.Sessions[SessionId].SessionVariables.ContainsKey(path.ToLower());
}
return false;
}

protected override bool IsValidPath(string path)
Expand All @@ -107,7 +98,10 @@ protected override bool IsValidPath(string path)

public void ClearContent(string path)
{
_memoryCache.Remove(ConnectionId + path.ToLower());
if (EndpointService.Instance.Sessions.ContainsKey(SessionId))
{
EndpointService.Instance.Sessions[SessionId].RemoveVariable(path);
}
}

public object ClearContentDynamicParameters(string path)
Expand All @@ -119,7 +113,12 @@ public IContentReader GetContentReader(string path)
{
Logger.Debug($"GetContentReader - {path} ");

return new MemoryCacheContentReaderWriter(ConnectionId + path.ToLower(), _memoryCache);
if (EndpointService.Instance.Sessions.ContainsKey(SessionId))
{
return new SessionStateReaderWriter(path.ToLower(), EndpointService.Instance.Sessions[SessionId]);
}

return null;
}

public object GetContentReaderDynamicParameters(string path)
Expand All @@ -131,13 +130,72 @@ public IContentWriter GetContentWriter(string path)
{
Logger.Debug($"GetContentWriter - {path} ");

return new MemoryCacheContentReaderWriter(ConnectionId + path.ToLower(), _memoryCache);
if (EndpointService.Instance.Sessions.ContainsKey(SessionId))
{
return new SessionStateReaderWriter(path.ToLower(), EndpointService.Instance.Sessions[SessionId]);
}

return null;
}

public object GetContentWriterDynamicParameters(string path)
{
throw new NotImplementedException();
}
#endregion DriveCmdletProvider overrides
} // VariableProvider
}

public class SessionStateReaderWriter : IContentWriter, IContentReader
{
private readonly string _name;
private readonly Models.SessionState _sessionState;

public SessionStateReaderWriter(string name, Models.SessionState sessionState)
{
_name = name;
_sessionState = sessionState;
}

public void Close()
{

}

public void Dispose()
{
}

public IList Read(long readCount)
{
var value = _sessionState.GetVariableValue(_name);
if (value != null)
{
return new ArrayList
{
value
};
}

return null;
}

public void Seek(long offset, SeekOrigin origin)
{

}

public IList Write(IList content)
{
if (content.Count == 1)
{
_sessionState.SetVariable(_name, content[0]);
}
else
{
_sessionState.SetVariable(_name, content);
}

return content;
}
}
}
8 changes: 8 additions & 0 deletions src/UniversalDashboard/Models/Connection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace UniversalDashboard.Models
{
public class Connection
{
public string Id { get; set; }
public string SessionId { get; set; }
}
}
Loading

0 comments on commit 61b0578

Please sign in to comment.