Skip to content

Commit d2de3f4

Browse files
author
Pete
committed
Merge branch 'hotfix-1.3.5' into develop
2 parents 38c3404 + cd84e51 commit d2de3f4

File tree

8 files changed

+187
-65
lines changed

8 files changed

+187
-65
lines changed

src/ServicePulse.Host.Tests/RegExTests.cs

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/ServicePulse.Host.Tests/ServicePulse.Host.Tests.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
<AppDesignerFolder>Properties</AppDesignerFolder>
1010
<RootNamespace>ServicePulse.Host.Tests</RootNamespace>
1111
<AssemblyName>ServicePulse.Host.Tests</AssemblyName>
12-
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
12+
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
1313
<FileAlignment>512</FileAlignment>
14+
<TargetFrameworkProfile />
1415
</PropertyGroup>
1516
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
1617
<DebugSymbols>true</DebugSymbols>
@@ -44,7 +45,7 @@
4445
<Reference Include="System.Xml" />
4546
</ItemGroup>
4647
<ItemGroup>
47-
<Compile Include="RegExTests.cs" />
48+
<Compile Include="VerifyAppConstantsJSTextReplacement.cs" />
4849
<Compile Include="Properties\AssemblyInfo.cs" />
4950
</ItemGroup>
5051
<ItemGroup>
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
namespace ServicePulse.Host.Tests
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
7+
using System.Text.RegularExpressions;
8+
using NUnit.Framework;
9+
10+
[TestFixture]
11+
public class VerifyAppConstantsJSTextReplacement
12+
{
13+
// app.constants.js holds the URL used to connect to SC
14+
// this both user configurable and updated during installation
15+
16+
Regex sc_url_regex = new Regex(@"(service_control_url\s*\:\s*['""])(.*?)(['""])");
17+
Regex version_regex = new Regex(@"(constant\s*\(\s*'version'\s*,\s*['""])(.*?)(['""])");
18+
19+
[Test]
20+
public void app_constants_js_validation()
21+
{
22+
var pathToConfig = Path.Combine("app.constants.js");
23+
Assert.IsTrue(File.Exists(pathToConfig), "app.constants.js does not exist - this will break installation code");
24+
25+
var config = File.ReadAllText(pathToConfig);
26+
var matchUrl = sc_url_regex.Match(config);
27+
Assert.IsTrue(matchUrl.Success, "regex failed to match app.constant.js for SC URI update");
28+
Uri uri;
29+
30+
Assert.IsTrue(Uri.TryCreate(matchUrl.Groups[2].Value, UriKind.Absolute, out uri), "regex match found in app.constants.js is not a valid URI");
31+
var matchVersion = version_regex.Match(config);
32+
Assert.IsTrue(matchVersion.Success, "regex failed to match app.constant.js for the version string");
33+
}
34+
35+
[Test]
36+
public void replace_version_regex_tests()
37+
{
38+
var configSnippets = new Dictionary<string, string>
39+
{
40+
{"1.3.0", @"angular.module('sc')
41+
.constant('version', '1.3.0')
42+
.constant('scConfig';"},
43+
{"1.3.0-beta1", @"angular.module('sc')
44+
.constant ( 'version' , '1.3.0-beta1')
45+
.constant('scConfig';"},
46+
{"", @"angular.module('sc')
47+
.constant('version' , '' )
48+
.constant('scConfig';"}
49+
};
50+
51+
foreach (var config in configSnippets)
52+
{
53+
var expectedResult = config.Key;
54+
var text = config.Value;
55+
56+
var match = version_regex.Match(text);
57+
Assert.IsTrue(match.Success, "regex failed to match version string");
58+
Assert.IsTrue(match.Groups[2].Value.Equals(expectedResult), string.Format("Version regex did not return expected value which was {0}", expectedResult));
59+
}
60+
}
61+
62+
[Test]
63+
public void test_regex_match_against_config_variants ()
64+
{
65+
var configVariations = new[]
66+
{
67+
// Standard 1.3 config
68+
@"angular.module('sc')
69+
.constant('version', '1.3.0')
70+
.constant('scConfig', {
71+
service_control_url:'http://localhost:33333/api/',
72+
service_pulse_url: 'http://platformupdate.particular.net/servicepulse.txt'
73+
});
74+
",
75+
// Added whitespace and custom FQDN
76+
@"angular.module('sc')
77+
.constant('version', '1.3.0')
78+
.constant('scConfig', {
79+
service_control_url : 'http://host.network.com:33333/api/' ,
80+
service_pulse_url: 'http://platformupdate.particular.net/servicepulse.txt'
81+
});
82+
",
83+
// Line breaks and flip urls
84+
@"angular.module('sc')
85+
.constant('version', '1.3.0')
86+
.constant('scConfig', {
87+
service_pulse_url:
88+
'http://platformupdate.particular.net/servicepulse.txt',
89+
service_control_url :
90+
'http://localhost:33333/api/'
91+
});
92+
",
93+
// 1.1 Config (config.js)
94+
@"
95+
'use strict';
96+
var SC = SC || {};
97+
SC.config = {
98+
service_control_url: 'http://localhost:33333/api/'
99+
};
100+
",
101+
102+
// 1.1 Config custom URL(config.js)
103+
@"
104+
'use strict';
105+
var SC = SC || {};
106+
SC.config = {
107+
service_control_url: 'http://gb-dev:33333/api/'
108+
};
109+
",
110+
// Double Quotes instead of single
111+
@"
112+
'use strict';
113+
var SC = SC || {};
114+
SC.config = {
115+
service_control_url:""http://localhost:33333/api/\""
116+
};
117+
"};
118+
119+
for (var i = 0; i < configVariations.Length; i++)
120+
{
121+
var config = configVariations[i];
122+
var match = sc_url_regex.Match(config);
123+
Assert.IsTrue(match.Success, string.Format("regex failed on config variation {0} ", i));
124+
Uri uri;
125+
Assert.IsTrue(Uri.TryCreate(match.Groups[2].Value, UriKind.Absolute, out uri), string.Format("regex match in did not return a URI in config variation {0}", i));
126+
}
127+
}
128+
}
129+
}

src/ServicePulse.Host/Commands/ExtractAndUpdateConstantsCommand.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ internal class ExtractAndUpdateConstantsCommand : AbstractCommand
99
{
1010
public override void Execute(HostArguments args)
1111
{
12-
#if !DEBUG
1312
ExtractApp(args);
1413
UpdateVersion(args.OutputPath);
1514
UpdateConfig(args.OutputPath, args.ServiceControlUrl);
16-
#endif
1715
}
1816

1917
static void ExtractApp(HostArguments args)
@@ -41,24 +39,19 @@ static void ExtractApp(HostArguments args)
4139
}
4240
}
4341
}
44-
45-
42+
4643
public static void UpdateConfig(string directoryPath, string serviceControlUrl)
4744
{
4845
var appJsPath = Path.Combine(directoryPath, "js/app.constants.js");
4946
var appJsCode = File.ReadAllText(appJsPath);
50-
51-
File.WriteAllText(appJsPath,
52-
Regex.Replace(appJsCode, @"(service_control_url: ')([\w:/]*)(')", "$1" + serviceControlUrl + "$3"));
47+
File.WriteAllText(appJsPath, Regex.Replace(appJsCode, @"(service_control_url\s*\:\s*['""])(.*?)(['""])", "$1" + serviceControlUrl + "$3"));
5348
}
5449

5550
public static void UpdateVersion(string directoryPath)
5651
{
5752
var appJsPath = Path.Combine(directoryPath, "js/app.constants.js");
5853
var appJsCode = File.ReadAllText(appJsPath);
59-
60-
var updatedContent = Regex.Replace(appJsCode, @"(constant\('version', ')([\w:/.-]*)(')", "${1}" + GetFileVersion() + "$3");
61-
54+
var updatedContent = Regex.Replace(appJsCode, @"(constant\(\s*'version'\s*,\s*')(.*?)(')", "${1}" + GetFileVersion() + "$3");
6255
File.WriteAllText(appJsPath, updatedContent);
6356
}
6457

src/ServicePulse.Host/Hosting/HostArguments.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public HostArguments(string[] args)
1717
{
1818
var executionMode = ExecutionMode.Run;
1919

20-
commands = new List<Type> { typeof(RemoveDeprecatedOveridesCommand), typeof(ExtractAndUpdateConstantsCommand), typeof(RunCommand) };
20+
commands = new List<Type> { typeof(RemoveDeprecatedOveridesCommand), typeof(RunCommand) };
2121
startMode = StartMode.Automatic;
2222
url = "http://localhost:8081";
2323
ServiceName = "Particular.ServicePulse";

src/ServicePulse.Host/app/layout/sidebar.html

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,42 @@
22
<ul class="nav nav-tabs nav-stacked main-menu">
33
<li>
44
<a href="/#/dashboard">
5-
<i class="fa fa-dashboard icon-white"></i><span class="hidden-md"> Dashboard</span>
5+
<i class="fa fa-dashboard icon-white"></i>
6+
<span class="hidden-sm">
7+
<span class="hidden-md"> Dashboard</span>
8+
</span>
69
</a>
710
</li>
811
<li>
912
<a href="/#/endpoints">
10-
<i class="fa fa-heart icon-white"></i><span class="hidden-md"> Endpoints Overview</span>
13+
<i class="fa fa-heart icon-white"></i>
14+
<span class="hidden-sm">
15+
<span class="hidden-md"> Endpoints Overview</span>
16+
</span>
1117
</a>
1218
</li>
1319
<li>
1420
<a href="/#/failedMessages">
15-
<i class="fa fa-envelope icon-white"></i><span class="hidden-md"> Failed Messages</span>
21+
<i class="fa fa-envelope icon-white"></i>
22+
<span class="hidden-sm">
23+
<span class="hidden-md"> Failed Messages</span>
24+
</span>
1625
</a>
1726
</li>
1827
<li>
1928
<a href="/#/customChecks">
20-
<i class="fa fa-check icon-white"></i><span class="hidden-md"> Custom Checks</span>
29+
<i class="fa fa-check icon-white"></i>
30+
<span class="hidden-sm">
31+
<span class="hidden-md"> Custom Check</span>
32+
</span>
2133
</a>
2234
</li>
2335
<li>
2436
<a href="/#/configuration">
25-
<i class="fa fa-cog icon-white"></i><span class="hidden-md"> Configuration</span>
37+
<i class="fa fa-cog icon-white"></i>
38+
<span class="hidden-sm">
39+
<span class="hidden-md"> Configuration</span>
40+
</span>
2641
</a>
2742
</li>
2843
</ul>

src/ServicePulse.Install.CustomActions/CustomAction.cs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -121,35 +121,52 @@ public static ActionResult ReadServiceControlUrlFromConfigJS(Session session)
121121
{
122122
Log(session, "Start custom action ReadServiceControlUrlFromConfigJS");
123123
var targetPath = session.Get("APPDIR");
124-
var configJsPath = Path.Combine(targetPath, @"app\config.js");
125-
var uri = @"http://localhost:33333/api/";
124+
var configFiles = new[]
125+
{
126+
@"app\config.js", /* Pre SC 1.3 path */
127+
@"app\js\app.constants.js" /* Post SC 1.3 path */
128+
};
129+
130+
string uri = null;
126131

127-
if (File.Exists(configJsPath))
132+
foreach (var file in configFiles)
128133
{
129-
var pattern = new Regex(@"service_control_url:\s*'(?<sc_uri>.*)'", RegexOptions.IgnoreCase);
130-
var matches = pattern.Match(File.ReadAllText(configJsPath));
131-
if (matches.Success)
134+
var filePath = Path.Combine(targetPath, file);
135+
if (!File.Exists(filePath))
136+
{
137+
Log(session, string.Format("File {0} does not exist - skipping", filePath));
138+
continue;
139+
}
140+
var extracted = ExtractServiceControlURI(filePath);
141+
if (extracted == null)
132142
{
133-
uri = matches.Groups["sc_uri"].Value;
134-
Log(session, string.Format(@"Extracted {0} from existing config.js", uri));
143+
Log(session, string.Format("No URI found in {0}", filePath));
135144
}
136145
else
137146
{
138-
Log(session, "No URI found - using default");
147+
Log(session, string.Format(@"Extracted {0} from {1}", extracted, filePath));
148+
uri = extracted;
139149
}
140150
}
141-
else
151+
152+
if (uri != null)
142153
{
143-
Log(session, string.Format("File not found {0}", configJsPath));
154+
session.Set("INST_URI", uri);
144155
}
145-
session.Set("INST_URI", uri);
146156
return ActionResult.Success;
147157
}
148158
finally
149159
{
150160
Log(session, "End custom action ReadServiceControlUrlFromConfigJS");
151161
}
152162
}
163+
164+
static string ExtractServiceControlURI(string file)
165+
{
166+
var pattern = new Regex(@"(service_control_url\s*\:\s*['""])(.*?)(['""])");
167+
var matches = pattern.Match(File.ReadAllText(file));
168+
return matches.Success ? matches.Groups[2].Value : null;
169+
}
153170

154171
static int RunNetsh(string command)
155172
{

src/Setup/ServicePulse.aip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@
338338
<ROW Action="Invalid_ServiceControlUrl_Msg" Type="1" Source="aicustact.dll" Target="MsgBox" WithoutSeq="true" Options="1" AdditionalSeq="AI_DATA_SETTER_4"/>
339339
<ROW Action="Invalid_ServicePulseUrl_Msg" Type="1" Source="aicustact.dll" Target="MsgBox" WithoutSeq="true" Options="1" AdditionalSeq="AI_DATA_SETTER_3"/>
340340
<ROW Action="Launch_Url" Type="1090" Source="viewer.exe" Target="http://www.particular.net/Installation-completed?installer=ServicePulse&amp;version=[ProductVersion]&amp;localURL=http://localhost:[INST_PORT_PULSE]" Options="1"/>
341+
<ROW Action="ReadExistingConfigs" Type="1" Source="ServicePulse.Install.CustomActions.CA.dll_1" Target="ReadServiceControlUrlFromConfigJS"/>
341342
<ROW Action="ReadServiceControlUrlFromConfigJS" Type="1" Source="ServicePulse.Install.CustomActions.CA.dll_1" Target="ReadServiceControlUrlFromConfigJS" WithoutSeq="true"/>
342343
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[ProgramFilesFolder]\Particular Software\ServicePulse\"/>
343344
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]" MultiBuildTarget="DefaultBuild:[ProgramMenuFolder]\Particular Software\"/>
@@ -384,6 +385,7 @@
384385
<ROW Action="AI_DATA_SETTER_2" Sequence="1601"/>
385386
<ROW Action="Stop_Service" Condition="( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) )" Sequence="211"/>
386387
<ROW Action="SetUrlAcl" Condition="( NOT Installed )" Sequence="6401"/>
388+
<ROW Action="ReadExistingConfigs" Condition="( NOT Installed ) AND ( UILevel &lt; 5 )" Sequence="1201"/>
387389
</COMPONENT>
388390
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
389391
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=&quot;&quot;" Sequence="749"/>

0 commit comments

Comments
 (0)