Skip to content

Commit 6990ead

Browse files
authored
feat: implement automatic sample configuration initialization
2 parents 81d8487 + 2baa15e commit 6990ead

File tree

14 files changed

+427
-300
lines changed

14 files changed

+427
-300
lines changed

.claude/settings.local.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
"mcp__serena",
1111
"Bash(sqlite3:*)",
1212
"Bash(dir:*)",
13-
"Bash(timeout:*)"
13+
"Bash(timeout:*)",
14+
"Bash(ping:*)",
15+
"Bash(findstr:*)"
1416
],
1517
"deny": [],
1618
"ask": []

ThingConnect.Pulse.Server/Controllers/ConfigurationController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public async Task<ActionResult> GetCurrentAsync()
143143
string? content = await _configurationService.GetCurrentConfigurationAsync();
144144
if (content == null)
145145
{
146-
return NotFound(new { message = "No active configuration found" });
146+
return NotFound(new { message = "No configuration found and no sample configuration available" });
147147
}
148148

149149
return Content(content, "text/plain");

ThingConnect.Pulse.Server/Program.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,14 @@ public static async Task Main(string[] args)
200200
SeedData.Initialize(context);
201201
}
202202

203+
// Initialize sample configuration if no configuration exists
204+
using (IServiceScope scope = app.Services.CreateScope())
205+
{
206+
IConfigurationService configService = scope.ServiceProvider.GetRequiredService<IConfigurationService>();
207+
await configService.InitializeSampleConfigurationAsync();
208+
Log.Information("Sample configuration initialization completed");
209+
}
210+
203211
app.UseDefaultFiles();
204212
app.UseStaticFiles();
205213

ThingConnect.Pulse.Server/Services/ConfigurationService.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public interface IConfigurationService
1414
Task<string?> GetVersionContentAsync(string versionId);
1515
Task<string?> GetCurrentConfigurationAsync();
1616
Task<ApplyResultDto> PreviewChangesAsync(string yamlContent);
17+
Task InitializeSampleConfigurationAsync();
1718
}
1819

1920
public sealed class ConfigurationService : IConfigurationService
@@ -188,6 +189,31 @@ public async Task<ApplyResultDto> PreviewChangesAsync(string yamlContent)
188189
};
189190
}
190191

192+
/// <summary>
193+
/// Initialize the system with sample configuration if no configuration versions exist
194+
/// </summary>
195+
public async Task InitializeSampleConfigurationAsync()
196+
{
197+
// Check if any configuration versions already exist
198+
var existingVersions = await _context.ConfigVersions.AnyAsync();
199+
if (existingVersions)
200+
{
201+
return; // Configuration already exists, skip initialization
202+
}
203+
204+
// Load sample configuration
205+
string sampleConfigPath = Path.Combine(AppContext.BaseDirectory, "sample-config.yaml");
206+
if (!File.Exists(sampleConfigPath))
207+
{
208+
return; // Sample config not available, skip initialization
209+
}
210+
211+
string sampleContent = await File.ReadAllTextAsync(sampleConfigPath);
212+
213+
// Apply sample configuration automatically
214+
await ApplyConfigurationAsync(sampleContent, "system", "Initial sample configuration applied automatically");
215+
}
216+
191217
private async Task<(int Added, int Updated, int Removed)> ApplyChangesToDatabaseAsync(
192218
List<Group> newGroups, List<Data.Endpoint> newEndpoints)
193219
{

ThingConnect.Pulse.Server/ThingConnect.Pulse.Server.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@
5353
<None Include="config.schema.json">
5454
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
5555
</None>
56+
<None Include="..\sample-config.yaml">
57+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
58+
<Link>sample-config.yaml</Link>
59+
</None>
5660
</ItemGroup>
5761

5862
<!-- Prevent auto-generation of web.config during publish -->

full-config.yaml

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
# ThingConnect.Pulse Configuration Sample
2+
# This file demonstrates all available configuration features
3+
# Refer to config.schema.json for validation rules
4+
5+
# Schema version - must be 1
6+
version: 1
7+
8+
# Global defaults applied to all targets unless overridden
9+
defaults:
10+
# How often to check each target (seconds)
11+
interval_seconds: 10
12+
13+
# Maximum time to wait for a response (milliseconds)
14+
timeout_ms: 1500
15+
16+
# Number of retry attempts on failure
17+
retries: 1
18+
19+
# HTTP-specific default settings
20+
http:
21+
# User agent string sent with HTTP requests
22+
user_agent: "ThingConnectPulse/1.0"
23+
24+
# Expected text in response body (empty = any response is OK)
25+
expect_text: ""
26+
27+
# Organization groups for logical grouping of targets
28+
groups:
29+
# Production floor equipment
30+
- id: production-floor
31+
name: "Production Floor"
32+
color: "#2E7D32" # Green for production
33+
sort_order: 10
34+
35+
# Press shop equipment (child of production floor)
36+
- id: press-shop
37+
name: "Press Shop"
38+
parent_id: production-floor
39+
color: "#1565C0" # Blue for press shop
40+
sort_order: 11
41+
42+
# Quality lab equipment
43+
- id: quality-lab
44+
name: "Quality Lab"
45+
color: "#7B1FA2" # Purple for quality
46+
sort_order: 20
47+
48+
# IT infrastructure
49+
- id: it-infrastructure
50+
name: "IT Infrastructure"
51+
color: "#E65100" # Orange for IT
52+
sort_order: 30
53+
54+
# Network devices (child of IT infrastructure)
55+
- id: network-devices
56+
name: "Network Devices"
57+
parent_id: it-infrastructure
58+
color: "#BF360C" # Dark orange for network
59+
sort_order: 31
60+
61+
# Monitoring targets - demonstrates all probe types and configuration options
62+
targets:
63+
64+
# ========================================
65+
# ICMP (Ping) Targets
66+
# ========================================
67+
68+
# Basic ICMP check with hostname
69+
- type: icmp
70+
host: plc-press-01.factory.local
71+
group: press-shop
72+
name: "PLC Press 01"
73+
notes: "Main press line PLC - critical for production"
74+
75+
# ICMP with custom settings and expected RTT
76+
- type: icmp
77+
host: hmi-station-02.factory.local
78+
group: press-shop
79+
name: "HMI Station 02"
80+
interval_seconds: 5 # Check every 5 seconds (override default)
81+
timeout_ms: 1000 # 1 second timeout (override default)
82+
retries: 2 # 2 retries (override default)
83+
expected_rtt_ms: 10 # Expected RTT under 10ms
84+
enabled: true # Explicitly enabled
85+
86+
# ICMP with IPv4 address
87+
- type: icmp
88+
host: 192.168.1.100
89+
group: quality-lab
90+
name: "Quality Management System"
91+
expected_rtt_ms: 25
92+
93+
# ICMP with IPv6 address
94+
- type: icmp
95+
host: 2001:db8::1
96+
group: it-infrastructure
97+
name: "IPv6 Test Server"
98+
enabled: false # Temporarily disabled
99+
notes: "IPv6 connectivity testing - currently disabled"
100+
101+
# ========================================
102+
# CIDR Range Targets
103+
# ========================================
104+
105+
# ICMP ping sweep of entire subnet
106+
- type: icmp
107+
cidr: 192.168.10.0/24
108+
group: production-floor
109+
name: "Production Subnet Sweep"
110+
interval_seconds: 30 # Less frequent for large ranges
111+
timeout_ms: 500 # Faster timeout for range scans
112+
notes: "Monitors entire production subnet for device availability"
113+
114+
# IPv6 CIDR range
115+
- type: icmp
116+
cidr: 2001:db8::/64
117+
group: it-infrastructure
118+
name: "IPv6 Network Range"
119+
interval_seconds: 60 # Even less frequent for IPv6 ranges
120+
121+
# ========================================
122+
# Wildcard IP Targets
123+
# ========================================
124+
125+
# Wildcard range (expands to .1-.254)
126+
- type: icmp
127+
wildcard: 10.10.1.*
128+
group: press-shop
129+
name: "Press Shop Network"
130+
interval_seconds: 15
131+
notes: "Auto-discovers devices in press shop subnet"
132+
133+
# ========================================
134+
# TCP Port Checks
135+
# ========================================
136+
137+
# Database server connectivity
138+
- type: tcp
139+
host: db-server.factory.local
140+
port: 1433 # SQL Server port
141+
group: it-infrastructure
142+
name: "Database Server"
143+
expected_rtt_ms: 5 # Database should be fast
144+
145+
# VNC access to HMI systems
146+
- type: tcp
147+
wildcard: 10.10.2.* # All HMI stations
148+
port: 5900 # VNC port
149+
group: press-shop
150+
name: "HMI VNC Access"
151+
timeout_ms: 2000 # VNC can be slower to respond
152+
153+
# SSH access to Linux systems
154+
- type: tcp
155+
host: linux-server.factory.local
156+
port: 22 # SSH port
157+
group: it-infrastructure
158+
name: "Linux Server SSH"
159+
160+
# Custom application port
161+
- type: tcp
162+
host: 192.168.20.50
163+
port: 8080 # Custom app port
164+
group: quality-lab
165+
name: "Lab Data Collector"
166+
interval_seconds: 20
167+
retries: 3
168+
169+
# TCP check on CIDR range
170+
- type: tcp
171+
cidr: 192.168.30.0/28 # Small range for specific service
172+
port: 502 # Modbus TCP port
173+
group: production-floor
174+
name: "Modbus Devices"
175+
timeout_ms: 3000 # Industrial protocols can be slow
176+
notes: "Modbus TCP connectivity to production devices"
177+
178+
# ========================================
179+
# HTTP/HTTPS Web Checks
180+
# ========================================
181+
182+
# Basic HTTP health check
183+
- type: http
184+
host: web-app.factory.local
185+
group: it-infrastructure
186+
name: "Factory Web Application"
187+
# port: 80 is default for HTTP
188+
189+
# HTTPS with custom port and path
190+
- type: http
191+
host: secure-app.factory.local
192+
port: 443 # HTTPS port
193+
http_path: "/health" # Custom health endpoint
194+
group: quality-lab
195+
name: "QMS Health Check"
196+
197+
# HTTP with content matching
198+
- type: http
199+
host: api.factory.local
200+
port: 8080
201+
http_path: "/api/status"
202+
http_match: "OK" # Must contain "OK" in response
203+
group: it-infrastructure
204+
name: "Factory API Status"
205+
interval_seconds: 30
206+
207+
# HTTP check with complex response validation
208+
- type: http
209+
host: dashboard.factory.local
210+
http_path: "/dashboard/health"
211+
http_match: '"status":"healthy"' # JSON response check
212+
group: production-floor
213+
name: "Production Dashboard"
214+
timeout_ms: 5000 # Web apps can be slower
215+
retries: 1 # Don't retry too aggressively for web
216+
notes: "Main production monitoring dashboard"
217+
218+
# HTTP range check with wildcard
219+
- type: http
220+
wildcard: 192.168.100.*
221+
http_path: "/status"
222+
http_match: "alive"
223+
group: quality-lab
224+
name: "Lab Equipment Web Status"
225+
interval_seconds: 45 # Less frequent for equipment
226+
227+
# HTTP check on CIDR range
228+
- type: http
229+
cidr: 10.0.50.0/29 # Small range of web services
230+
port: 8080
231+
http_path: "/health"
232+
group: it-infrastructure
233+
name: "Microservices Health"
234+
timeout_ms: 10000 # Allow time for microservice startup
235+
236+
# Custom HTTP check with all options
237+
- type: http
238+
host: critical-system.factory.local
239+
port: 9443 # Custom HTTPS port
240+
http_path: "/api/v1/health"
241+
http_match: '"service":"running","database":"connected"'
242+
group: production-floor
243+
name: "Critical Production System"
244+
interval_seconds: 5 # Very frequent for critical system
245+
timeout_ms: 2000
246+
retries: 3 # Multiple retries for critical system
247+
expected_rtt_ms: 100 # Should respond quickly
248+
enabled: true
249+
notes: "Mission critical system - requires immediate attention if down"
250+
251+
# ========================================
252+
# Advanced Configuration Examples
253+
# ========================================
254+
255+
# Minimal configuration (using all defaults)
256+
- type: icmp
257+
host: simple-device.factory.local
258+
group: production-floor
259+
260+
# Disabled target for maintenance
261+
- type: tcp
262+
host: maintenance-server.factory.local
263+
port: 80
264+
group: it-infrastructure
265+
name: "Maintenance Server (Offline)"
266+
enabled: false
267+
notes: "Temporarily offline for maintenance - re-enable after 2024-09-15"
268+
269+
# High-frequency monitoring for critical path
270+
- type: http
271+
host: critical-path.factory.local
272+
http_path: "/critical/status"
273+
http_match: "operational"
274+
group: production-floor
275+
name: "Critical Path Monitor"
276+
interval_seconds: 1 # Check every second!
277+
timeout_ms: 500 # Must be fast
278+
retries: 0 # No retries - immediate alerts
279+
expected_rtt_ms: 50 # Very fast response expected
280+
notes: "Critical manufacturing process - zero tolerance for downtime"

0 commit comments

Comments
 (0)