🔷 🔗 Integration Guides - TuskLang for C# - "Connect Everything"
🔗 Integration Guides - TuskLang for C# - "Connect Everything"
Master TuskLang integrations - Connect with databases, APIs, cloud services, and enterprise systems!
Integrations are where TuskLang becomes truly powerful. Learn how to connect your dynamic configuration system with databases, APIs, cloud services, monitoring tools, and enterprise systems.
🎯 Integration Philosophy
"We Don't Bow to Any King"
- Universal connectivity - Connect with any service or system - Standard protocols - Use industry-standard integration patterns - Real-time sync - Keep configurations in sync with external systems - Bi-directional - Read from and write to external systems - Enterprise ready - Integrate with enterprise-grade systemsWhy Integrations Matter?
- Data synchronization - Keep configurations in sync with external data - Real-time updates - React to changes in external systems - System orchestration - Coordinate multiple systems - Automation - Automate configuration management - Enterprise connectivity - Connect with existing enterprise systems🗄️ Database Integrations
PostgreSQL Integration
// PostgreSQLIntegrationService.cs
using TuskLang;
using TuskLang.Adapters;
using Npgsql;public class PostgreSQLIntegrationService
{
private readonly TuskLang _parser;
private readonly PostgreSQLAdapter _postgresAdapter;
private readonly ILogger<PostgreSQLIntegrationService> _logger;
public PostgreSQLIntegrationService(ILogger<PostgreSQLIntegrationService> logger)
{
_parser = new TuskLang();
_postgresAdapter = new PostgreSQLAdapter(new PostgreSQLConfig
{
Host = Environment.GetEnvironmentVariable("POSTGRES_HOST"),
Port = int.Parse(Environment.GetEnvironmentVariable("POSTGRES_PORT")),
Database = Environment.GetEnvironmentVariable("POSTGRES_DB"),
User = Environment.GetEnvironmentVariable("POSTGRES_USER"),
Password = Environment.GetEnvironmentVariable("POSTGRES_PASSWORD"),
SslMode = "require"
}, new PoolConfig
{
MaxOpenConns = 100,
MaxIdleConns = 50,
ConnMaxLifetime = 300000
});
_parser.SetDatabaseAdapter(_postgresAdapter);
_logger = logger;
}
public async Task<Dictionary<string, object>> GetConfigurationWithPostgreSQLAsync(string filePath)
{
// Parse configuration with PostgreSQL integration
var config = _parser.ParseFile(filePath);
// Sync with PostgreSQL data
await SyncWithPostgreSQLAsync(config);
return config;
}
private async Task SyncWithPostgreSQLAsync(Dictionary<string, object> config)
{
try
{
// Sync user data
if (config.ContainsKey("users"))
{
var users = await _postgresAdapter.QueryAsync(@"
SELECT id, username, email, role, created_at
FROM users
WHERE active = true
");
config["users"]["data"] = users;
config["users"]["count"] = users.Count;
config["users"]["last_sync"] = DateTime.UtcNow;
}
// Sync application settings
if (config.ContainsKey("app_settings"))
{
var settings = await _postgresAdapter.QueryAsync(@"
SELECT key, value, type, updated_at
FROM app_settings
WHERE active = true
");
var settingsDict = new Dictionary<string, object>();
foreach (var setting in settings)
{
settingsDict[setting["key"].ToString()] = setting["value"];
}
config["app_settings"]["database"] = settingsDict;
}
// Sync feature flags
if (config.ContainsKey("features"))
{
var features = await _postgresAdapter.QueryAsync(@"
SELECT name, enabled, rollout_percentage, target_users
FROM feature_flags
WHERE active = true
");
var featuresDict = new Dictionary<string, object>();
foreach (var feature in features)
{
featuresDict[feature["name"].ToString()] = new Dictionary<string, object>
{
["enabled"] = feature["enabled"],
["rollout_percentage"] = feature["rollout_percentage"],
["target_users"] = feature["target_users"]
};
}
config["features"]["database"] = featuresDict;
}
_logger.LogInformation("Successfully synced configuration with PostgreSQL");
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to sync configuration with PostgreSQL");
throw;
}
}
public async Task UpdateConfigurationInPostgreSQLAsync(string filePath, Dictionary<string, object> changes)
{
try
{
foreach (var change in changes)
{
switch (change.Key)
{
case "app_settings":
await UpdateAppSettingsAsync(change.Value as Dictionary<string, object>);
break;
case "features":
await UpdateFeatureFlagsAsync(change.Value as Dictionary<string, object>);
break;
case "users":
await UpdateUserSettingsAsync(change.Value as Dictionary<string, object>);
break;
}
}
_logger.LogInformation("Successfully updated configuration in PostgreSQL");
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to update configuration in PostgreSQL");
throw;
}
}
private async Task UpdateAppSettingsAsync(Dictionary<string, object>? settings)
{
if (settings == null) return;
foreach (var setting in settings)
{
await _postgresAdapter.ExecuteAsync(@"
INSERT INTO app_settings (key, value, type, updated_at)
VALUES (@key, @value, 'string', @updated_at)
ON CONFLICT (key)
DO UPDATE SET value = @value, updated_at = @updated_at
", new Dictionary<string, object>
{
["key"] = setting.Key,
["value"] = setting.Value,
["updated_at"] = DateTime.UtcNow
});
}
}
private async Task UpdateFeatureFlagsAsync(Dictionary<string, object>? features)
{
if (features == null) return;
foreach (var feature in features)
{
var featureData = feature.Value as Dictionary<string, object>;
if (featureData != null)
{
await _postgresAdapter.ExecuteAsync(@"
INSERT INTO feature_flags (name, enabled, rollout_percentage, target_users, updated_at)
VALUES (@name, @enabled, @rollout_percentage, @target_users, @updated_at)
ON CONFLICT (name)
DO UPDATE SET enabled = @enabled, rollout_percentage = @rollout_percentage,
target_users = @target_users, updated_at = @updated_at
", new Dictionary<string, object>
{
["name"] = feature.Key,
["enabled"] = featureData["enabled"],
["rollout_percentage"] = featureData["rollout_percentage"],
["target_users"] = featureData["target_users"],
["updated_at"] = DateTime.UtcNow
});
}
}
}
private async Task UpdateUserSettingsAsync(Dictionary<string, object>? userSettings)
{
if (userSettings == null) return;
foreach (var setting in userSettings)
{
await _postgresAdapter.ExecuteAsync(@"
INSERT INTO user_settings (user_id, setting_key, setting_value, updated_at)
VALUES (@user_id, @setting_key, @setting_value, @updated_at)
ON CONFLICT (user_id, setting_key)
DO UPDATE SET setting_value = @setting_value, updated_at = @updated_at
", new Dictionary<string, object>
{
["user_id"] = setting.Key,
["setting_key"] = "preference",
["setting_value"] = setting.Value,
["updated_at"] = DateTime.UtcNow
});
}
}
}
PostgreSQL TSK Configuration
postgresql-integration.tsk - PostgreSQL integration
$db_host: @env("POSTGRES_HOST", "localhost")
$db_port: @env("POSTGRES_PORT", "5432")
$db_name: @env("POSTGRES_DB", "tuskapp")
$db_user: @env("POSTGRES_USER", "postgres")
$db_password: @env.secure("POSTGRES_PASSWORD")[database]
postgresql {
host: $db_host
port: $db_port
name: $db_name
user: $db_user
password: $db_password
ssl: true
pool {
max_open_conns: 100
max_idle_conns: 50
conn_max_lifetime: "5m"
}
}
[users]
User data from PostgreSQL
data: @query("SELECT id, username, email, role, created_at FROM users WHERE active = true")
count: @query("SELECT COUNT(*) FROM users WHERE active = true")
last_sync: @date.now()[app_settings]
Application settings from PostgreSQL
database: @query.to_dict("SELECT key, value FROM app_settings WHERE active = true", "key", "value")
default {
theme: "light"
language: "en"
timezone: "UTC"
}[features]
Feature flags from PostgreSQL
database: @query.to_dict("SELECT name, enabled, rollout_percentage FROM feature_flags WHERE active = true", "name", "enabled")
local {
debug_mode: true
test_features: true
}[sync]
Sync configuration
auto_sync: true
sync_interval: "5m"
last_sync: @date.now()
☁️ Cloud Service Integrations
AWS Integration
// AWSIntegrationService.cs
using TuskLang;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.SecretsManager;
using Amazon.SecretsManager.Model;
using Amazon.CloudWatch;
using Amazon.CloudWatch.Model;public class AWSIntegrationService
{
private readonly TuskLang _parser;
private readonly IAmazonS3 _s3Client;
private readonly IAmazonSecretsManager _secretsClient;
private readonly IAmazonCloudWatch _cloudWatchClient;
private readonly ILogger<AWSIntegrationService> _logger;
public AWSIntegrationService(ILogger<AWSIntegrationService> logger)
{
_parser = new TuskLang();
_s3Client = new AmazonS3Client();
_secretsClient = new AmazonSecretsManagerClient();
_cloudWatchClient = new AmazonCloudWatchClient();
_logger = logger;
// Configure parser with AWS operators
_parser.SetCustomOperatorProvider(new AWSOperatorProvider(_s3Client, _secretsClient, _cloudWatchClient));
}
public async Task<Dictionary<string, object>> GetConfigurationWithAWSAsync(string filePath)
{
// Parse configuration with AWS integration
var config = _parser.ParseFile(filePath);
// Sync with AWS services
await SyncWithAWSServicesAsync(config);
return config;
}
private async Task SyncWithAWSServicesAsync(Dictionary<string, object> config)
{
try
{
// Sync with S3
if (config.ContainsKey("s3"))
{
await SyncWithS3Async(config["s3"] as Dictionary<string, object>);
}
// Sync with Secrets Manager
if (config.ContainsKey("secrets"))
{
await SyncWithSecretsManagerAsync(config["secrets"] as Dictionary<string, object>);
}
// Sync with CloudWatch
if (config.ContainsKey("monitoring"))
{
await SyncWithCloudWatchAsync(config["monitoring"] as Dictionary<string, object>);
}
_logger.LogInformation("Successfully synced configuration with AWS services");
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to sync configuration with AWS services");
throw;
}
}
private async Task SyncWithS3Async(Dictionary<string, object>? s3Config)
{
if (s3Config == null) return;
var bucketName = s3Config["bucket"].ToString();
var key = s3Config["key"].ToString();
try
{
var response = await _s3Client.GetObjectAsync(bucketName, key);
using var reader = new StreamReader(response.ResponseStream);
var content = await reader.ReadToEndAsync();
s3Config["content"] = content;
s3Config["last_modified"] = response.LastModified;
s3Config["size"] = response.ContentLength;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to sync with S3: {Bucket}/{Key}", bucketName, key);
s3Config["error"] = ex.Message;
}
}
private async Task SyncWithSecretsManagerAsync(Dictionary<string, object>? secretsConfig)
{
if (secretsConfig == null) return;
var secretNames = secretsConfig["names"] as List<object>;
if (secretNames != null)
{
var secrets = new Dictionary<string, object>();
foreach (var secretName in secretNames)
{
try
{
var request = new GetSecretValueRequest
{
SecretId = secretName.ToString()
};
var response = await _secretsClient.GetSecretValueAsync(request);
secrets[secretName.ToString()] = response.SecretString;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get secret: {SecretName}", secretName);
secrets[secretName.ToString()] = "ERROR";
}
}
secretsConfig["values"] = secrets;
}
}
private async Task SyncWithCloudWatchAsync(Dictionary<string, object>? monitoringConfig)
{
if (monitoringConfig == null) return;
var metrics = monitoringConfig["metrics"] as List<object>;
if (metrics != null)
{
var metricData = new Dictionary<string, object>();
foreach (var metric in metrics)
{
var metricInfo = metric as Dictionary<string, object>;
if (metricInfo != null)
{
try
{
var request = new GetMetricStatisticsRequest
{
Namespace = metricInfo["namespace"].ToString(),
MetricName = metricInfo["name"].ToString(),
StartTime = DateTime.UtcNow.AddHours(-1),
EndTime = DateTime.UtcNow,
Period = 300, // 5 minutes
Statistics = new List<string> { "Average", "Maximum", "Minimum" }
};
var response = await _cloudWatchClient.GetMetricStatisticsAsync(request);
if (response.Datapoints.Any())
{
var latest = response.Datapoints.OrderByDescending(d => d.Timestamp).First();
metricData[metricInfo["name"].ToString()] = new Dictionary<string, object>
{
["average"] = latest.Average,
["maximum"] = latest.Maximum,
["minimum"] = latest.Minimum,
["timestamp"] = latest.Timestamp
};
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get metric: {MetricName}", metricInfo["name"]);
}
}
}
monitoringConfig["data"] = metricData;
}
}
public async Task UpdateConfigurationInAWSAsync(string filePath, Dictionary<string, object> changes)
{
try
{
foreach (var change in changes)
{
switch (change.Key)
{
case "s3":
await UpdateS3ConfigurationAsync(change.Value as Dictionary<string, object>);
break;
case "secrets":
await UpdateSecretsConfigurationAsync(change.Value as Dictionary<string, object>);
break;
}
}
_logger.LogInformation("Successfully updated configuration in AWS");
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to update configuration in AWS");
throw;
}
}
private async Task UpdateS3ConfigurationAsync(Dictionary<string, object>? s3Config)
{
if (s3Config == null) return;
var bucketName = s3Config["bucket"].ToString();
var key = s3Config["key"].ToString();
var content = s3Config["content"].ToString();
try
{
var request = new PutObjectRequest
{
BucketName = bucketName,
Key = key,
ContentBody = content
};
await _s3Client.PutObjectAsync(request);
_logger.LogInformation("Successfully updated S3 object: {Bucket}/{Key}", bucketName, key);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to update S3 object: {Bucket}/{Key}", bucketName, key);
throw;
}
}
private async Task UpdateSecretsConfigurationAsync(Dictionary<string, object>? secretsConfig)
{
if (secretsConfig == null) return;
var secrets = secretsConfig["values"] as Dictionary<string, object>;
if (secrets != null)
{
foreach (var secret in secrets)
{
try
{
var request = new UpdateSecretRequest
{
SecretId = secret.Key,
SecretString = secret.Value.ToString()
};
await _secretsClient.UpdateSecretAsync(request);
_logger.LogInformation("Successfully updated secret: {SecretName}", secret.Key);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to update secret: {SecretName}", secret.Key);
}
}
}
}
}
public class AWSOperatorProvider : ICustomOperatorProvider
{
private readonly IAmazonS3 _s3Client;
private readonly IAmazonSecretsManager _secretsClient;
private readonly IAmazonCloudWatch _cloudWatchClient;
public AWSOperatorProvider(
IAmazonS3 s3Client,
IAmazonSecretsManager secretsClient,
IAmazonCloudWatch cloudWatchClient)
{
_s3Client = s3Client;
_secretsClient = secretsClient;
_cloudWatchClient = cloudWatchClient;
}
public async Task<object> ExecuteAsync(string operatorName, object[] parameters)
{
return operatorName switch
{
"aws.s3.get" => await GetS3ObjectAsync(parameters),
"aws.secrets.get" => await GetSecretAsync(parameters),
"aws.cloudwatch.metric" => await GetMetricAsync(parameters),
_ => throw new ArgumentException($"Unknown AWS operator: {operatorName}")
};
}
private async Task<string> GetS3ObjectAsync(object[] parameters)
{
var bucketName = parameters[0].ToString();
var key = parameters[1].ToString();
var response = await _s3Client.GetObjectAsync(bucketName, key);
using var reader = new StreamReader(response.ResponseStream);
return await reader.ReadToEndAsync();
}
private async Task<string> GetSecretAsync(object[] parameters)
{
var secretName = parameters[0].ToString();
var request = new GetSecretValueRequest
{
SecretId = secretName
};
var response = await _secretsClient.GetSecretValueAsync(request);
return response.SecretString;
}
private async Task<double> GetMetricAsync(object[] parameters)
{
var namespace_ = parameters[0].ToString();
var metricName = parameters[1].ToString();
var statistic = parameters[2].ToString();
var request = new GetMetricStatisticsRequest
{
Namespace = namespace_,
MetricName = metricName,
StartTime = DateTime.UtcNow.AddMinutes(-5),
EndTime = DateTime.UtcNow,
Period = 300,
Statistics = new List<string> { statistic }
};
var response = await _cloudWatchClient.GetMetricStatisticsAsync(request);
if (response.Datapoints.Any())
{
var latest = response.Datapoints.OrderByDescending(d => d.Timestamp).First();
return statistic switch
{
"Average" => latest.Average ?? 0,
"Maximum" => latest.Maximum ?? 0,
"Minimum" => latest.Minimum ?? 0,
_ => 0
};
}
return 0;
}
}
AWS TSK Configuration
aws-integration.tsk - AWS integration
$aws_region: @env("AWS_REGION", "us-east-1")
$aws_profile: @env("AWS_PROFILE", "default")[aws]
region: $aws_region
profile: $aws_profile
[s3]
bucket: @env("S3_CONFIG_BUCKET", "tusk-config")
key: @env("S3_CONFIG_KEY", "config/app.tsk")
content: @aws.s3.get($s3.bucket, $s3.key)
last_modified: @aws.s3.last_modified($s3.bucket, $s3.key)
size: @aws.s3.size($s3.bucket, $s3.key)
[secrets]
names: ["database_password", "api_key", "jwt_secret", "redis_password"]
values: {
database_password: @aws.secrets.get("database_password")
api_key: @aws.secrets.get("api_key")
jwt_secret: @aws.secrets.get("jwt_secret")
redis_password: @aws.secrets.get("redis_password")
}
[monitoring]
metrics {
cpu_usage: @aws.cloudwatch.metric("AWS/EC2", "CPUUtilization", "Average")
memory_usage: @aws.cloudwatch.metric("AWS/EC2", "MemoryUtilization", "Average")
disk_usage: @aws.cloudwatch.metric("AWS/EC2", "DiskUtilization", "Average")
network_in: @aws.cloudwatch.metric("AWS/EC2", "NetworkIn", "Average")
network_out: @aws.cloudwatch.metric("AWS/EC2", "NetworkOut", "Average")
}
[lambda]
functions {
config_processor: @env("LAMBDA_CONFIG_PROCESSOR", "tusk-config-processor")
config_validator: @env("LAMBDA_CONFIG_VALIDATOR", "tusk-config-validator")
}
[cloudformation]
stack_name: @env("CLOUDFORMATION_STACK", "tusk-config-stack")
template_url: @env("CLOUDFORMATION_TEMPLATE", "https://s3.amazonaws.com/tusk-templates/config-stack.yaml")
🔌 API Integrations
REST API Integration
// RESTAPIIntegrationService.cs
using TuskLang;
using System.Net.Http;
using System.Text.Json;public class RESTAPIIntegrationService
{
private readonly TuskLang _parser;
private readonly HttpClient _httpClient;
private readonly ILogger<RESTAPIIntegrationService> _logger;
public RESTAPIIntegrationService(ILogger<RESTAPIIntegrationService> logger)
{
_parser = new TuskLang();
_httpClient = new HttpClient();
_logger = logger;
// Configure parser with HTTP operators
_parser.SetCustomOperatorProvider(new HTTPOperatorProvider(_httpClient));
}
public async Task<Dictionary<string, object>> GetConfigurationWithAPIAsync(string filePath)
{
// Parse configuration with API integration
var config = _parser.ParseFile(filePath);
// Sync with external APIs
await SyncWithAPIsAsync(config);
return config;
}
private async Task SyncWithAPIsAsync(Dictionary<string, object> config)
{
try
{
// Sync with user management API
if (config.ContainsKey("users"))
{
await SyncWithUserAPIAsync(config["users"] as Dictionary<string, object>);
}
// Sync with payment API
if (config.ContainsKey("payments"))
{
await SyncWithPaymentAPIAsync(config["payments"] as Dictionary<string, object>);
}
// Sync with notification API
if (config.ContainsKey("notifications"))
{
await SyncWithNotificationAPIAsync(config["notifications"] as Dictionary<string, object>);
}
_logger.LogInformation("Successfully synced configuration with APIs");
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to sync configuration with APIs");
throw;
}
}
private async Task SyncWithUserAPIAsync(Dictionary<string, object>? userConfig)
{
if (userConfig == null) return;
var apiUrl = userConfig["api_url"].ToString();
try
{
var response = await _httpClient.GetAsync($"{apiUrl}/users");
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
var users = JsonSerializer.Deserialize<List<Dictionary<string, object>>>(content);
userConfig["data"] = users;
userConfig["count"] = users?.Count ?? 0;
userConfig["last_sync"] = DateTime.UtcNow;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to sync with user API: {ApiUrl}", apiUrl);
userConfig["error"] = ex.Message;
}
}
private async Task SyncWithPaymentAPIAsync(Dictionary<string, object>? paymentConfig)
{
if (paymentConfig == null) return;
var apiUrl = paymentConfig["api_url"].ToString();
var apiKey = paymentConfig["api_key"].ToString();
try
{
_httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey);
var response = await _httpClient.GetAsync($"{apiUrl}/payments/stats");
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
var stats = JsonSerializer.Deserialize<Dictionary<string, object>>(content);
paymentConfig["stats"] = stats;
paymentConfig["last_sync"] = DateTime.UtcNow;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to sync with payment API: {ApiUrl}", apiUrl);
paymentConfig["error"] = ex.Message;
}
}
private async Task SyncWithNotificationAPIAsync(Dictionary<string, object>? notificationConfig)
{
if (notificationConfig == null) return;
var apiUrl = notificationConfig["api_url"].ToString();
try
{
var response = await _httpClient.GetAsync($"{apiUrl}/notifications/templates");
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
var templates = JsonSerializer.Deserialize<List<Dictionary<string, object>>>(content);
notificationConfig["templates"] = templates;
notificationConfig["last_sync"] = DateTime.UtcNow;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to sync with notification API: {ApiUrl}", apiUrl);
notificationConfig["error"] = ex.Message;
}
}
public async Task UpdateConfigurationViaAPIAsync(string filePath, Dictionary<string, object> changes)
{
try
{
foreach (var change in changes)
{
switch (change.Key)
{
case "users":
await UpdateUserAPIAsync(change.Value as Dictionary<string, object>);
break;
case "payments":
await UpdatePaymentAPIAsync(change.Value as Dictionary<string, object>);
break;
case "notifications":
await UpdateNotificationAPIAsync(change.Value as Dictionary<string, object>);
break;
}
}
_logger.LogInformation("Successfully updated configuration via APIs");
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to update configuration via APIs");
throw;
}
}
private async Task UpdateUserAPIAsync(Dictionary<string, object>? userConfig)
{
if (userConfig == null) return;
var apiUrl = userConfig["api_url"].ToString();
var updates = userConfig["updates"] as Dictionary<string, object>;
if (updates != null)
{
foreach (var update in updates)
{
try
{
var json = JsonSerializer.Serialize(update.Value);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await _httpClient.PutAsync($"{apiUrl}/users/{update.Key}", content);
response.EnsureSuccessStatusCode();
_logger.LogInformation("Successfully updated user via API: {UserId}", update.Key);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to update user via API: {UserId}", update.Key);
}
}
}
}
private async Task UpdatePaymentAPIAsync(Dictionary<string, object>? paymentConfig)
{
if (paymentConfig == null) return;
var apiUrl = paymentConfig["api_url"].ToString();
var apiKey = paymentConfig["api_key"].ToString();
var updates = paymentConfig["updates"] as Dictionary<string, object>;
if (updates != null)
{
_httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey);
foreach (var update in updates)
{
try
{
var json = JsonSerializer.Serialize(update.Value);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await _httpClient.PutAsync($"{apiUrl}/payments/{update.Key}", content);
response.EnsureSuccessStatusCode();
_logger.LogInformation("Successfully updated payment via API: {PaymentId}", update.Key);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to update payment via API: {PaymentId}", update.Key);
}
}
}
}
private async Task UpdateNotificationAPIAsync(Dictionary<string, object>? notificationConfig)
{
if (notificationConfig == null) return;
var apiUrl = notificationConfig["api_url"].ToString();
var updates = notificationConfig["updates"] as Dictionary<string, object>;
if (updates != null)
{
foreach (var update in updates)
{
try
{
var json = JsonSerializer.Serialize(update.Value);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await _httpClient.PutAsync($"{apiUrl}/notifications/templates/{update.Key}", content);
response.EnsureSuccessStatusCode();
_logger.LogInformation("Successfully updated notification template via API: {TemplateId}", update.Key);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to update notification template via API: {TemplateId}", update.Key);
}
}
}
}
}
public class HTTPOperatorProvider : ICustomOperatorProvider
{
private readonly HttpClient _httpClient;
public HTTPOperatorProvider(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<object> ExecuteAsync(string operatorName, object[] parameters)
{
return operatorName switch
{
"http.get" => await HttpGetAsync(parameters),
"http.post" => await HttpPostAsync(parameters),
"http.put" => await HttpPutAsync(parameters),
"http.delete" => await HttpDeleteAsync(parameters),
_ => throw new ArgumentException($"Unknown HTTP operator: {operatorName}")
};
}
private async Task<string> HttpGetAsync(object[] parameters)
{
var url = parameters[0].ToString();
var response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
private async Task<string> HttpPostAsync(object[] parameters)
{
var url = parameters[0].ToString();
var data = parameters[1];
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(url, content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
private async Task<string> HttpPutAsync(object[] parameters)
{
var url = parameters[0].ToString();
var data = parameters[1];
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await _httpClient.PutAsync(url, content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
private async Task<string> HttpDeleteAsync(object[] parameters)
{
var url = parameters[0].ToString();
var response = await _httpClient.DeleteAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}
REST API TSK Configuration
rest-api-integration.tsk - REST API integration
$api_base_url: @env("API_BASE_URL", "https://api.example.com")
$api_key: @env.secure("API_KEY")[api]
base_url: $api_base_url
key: $api_key
timeout: "30s"
retries: 3
[users]
api_url: "${api.base_url}/users"
data: @http.get("${users.api_url}")
count: @http.get("${users.api_url}/count")
last_sync: @date.now()
[payments]
api_url: "${api.base_url}/payments"
api_key: $api_key
stats: @http.get("${payments.api_url}/stats")
methods: @http.get("${payments.api_url}/methods")
last_sync: @date.now()
[notifications]
api_url: "${api.base_url}/notifications"
templates: @http.get("${notifications.api_url}/templates")
channels: @http.get("${notifications.api_url}/channels")
last_sync: @date.now()
[external_services]
weather {
url: "https://api.weatherapi.com/v1/current.json"
key: @env.secure("WEATHER_API_KEY")
data: @http.get("${weather.url}?key=${weather.key}&q=auto:ip")
}
currency {
url: "https://api.exchangerate-api.com/v4/latest/USD"
data: @http.get("${currency.url}")
}
[webhooks]
endpoints {
user_created: @env("WEBHOOK_USER_CREATED", "")
payment_processed: @env("WEBHOOK_PAYMENT_PROCESSED", "")
notification_sent: @env("WEBHOOK_NOTIFICATION_SENT", "")
}
[rate_limiting]
requests_per_minute: 100
burst_limit: 20
retry_after: "60s"
📊 Monitoring Integrations
Prometheus Integration
// PrometheusIntegrationService.cs
using TuskLang;
using Prometheus;
using Microsoft.Extensions.Hosting;public class PrometheusIntegrationService : BackgroundService
{
private readonly TuskLang _parser;
private readonly IMetricsCollector _metricsCollector;
private readonly ILogger<PrometheusIntegrationService> _logger;
// Prometheus metrics
private readonly Counter _configurationParsesTotal;
private readonly Histogram _configurationParseDuration;
private readonly Gauge _configurationSize;
private readonly Counter _configurationErrorsTotal;
public PrometheusIntegrationService(
IMetricsCollector metricsCollector,
ILogger<PrometheusIntegrationService> logger)
{
_parser = new TuskLang();
_metricsCollector = metricsCollector;
_logger = logger;
// Initialize Prometheus metrics
_configurationParsesTotal = Metrics.CreateCounter("tusklang_configuration_parses_total",
"Total number of configuration parses", new CounterConfiguration
{
LabelNames = new[] { "file_path", "status" }
});
_configurationParseDuration = Metrics.CreateHistogram("tusklang_configuration_parse_duration_seconds",
"Configuration parse duration", new HistogramConfiguration
{
LabelNames = new[] { "file_path" },
Buckets = new[] { 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0 }
});
_configurationSize = Metrics.CreateGauge("tusklang_configuration_size_bytes",
"Configuration file size in bytes", new GaugeConfiguration
{
LabelNames = new[] { "file_path" }
});
_configurationErrorsTotal = Metrics.CreateCounter("tusklang_configuration_errors_total",
"Total number of configuration errors", new CounterConfiguration
{
LabelNames = new[] { "file_path", "error_type" }
});
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
// Collect and expose metrics
await CollectMetricsAsync();
await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to collect metrics");
await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
}
}
}
private async Task CollectMetricsAsync()
{
// Collect system metrics
var systemMetrics = await _metricsCollector.CollectAsync();
// Update Prometheus metrics
foreach (var metric in systemMetrics)
{
switch (metric.Key)
{
case "cpu_usage":
Metrics.CreateGauge("system_cpu_usage_percent", "CPU usage percentage").Set(Convert.ToDouble(metric.Value));
break;
case "memory_usage":
Metrics.CreateGauge("system_memory_usage_percent", "Memory usage percentage").Set(Convert.ToDouble(metric.Value));
break;
case "requests_per_second":
Metrics.CreateGauge("system_requests_per_second", "Requests per second").Set(Convert.ToDouble(metric.Value));
break;
case "error_rate":
Metrics.CreateGauge("system_error_rate", "Error rate").Set(Convert.ToDouble(metric.Value));
break;
}
}
}
public async Task<Dictionary<string, object>> GetConfigurationWithMetricsAsync(string filePath)
{
var stopwatch = Stopwatch.StartNew();
try
{
// Update configuration size metric
var fileInfo = new FileInfo(filePath);
_configurationSize.WithLabels(filePath).Set(fileInfo.Length);
// Parse configuration
var config = _parser.ParseFile(filePath);
stopwatch.Stop();
// Record success metrics
_configurationParsesTotal.WithLabels(filePath, "success").Inc();
_configurationParseDuration.WithLabels(filePath).Observe(stopwatch.Elapsed.TotalSeconds);
_logger.LogInformation("Configuration parsed successfully in {Duration}ms", stopwatch.ElapsedMilliseconds);
return config;
}
catch (Exception ex)
{
stopwatch.Stop();
// Record error metrics
_configurationParsesTotal.WithLabels(filePath, "error").Inc();
_configurationErrorsTotal.WithLabels(filePath, ex.GetType().Name).Inc();
_logger.LogError(ex, "Configuration parse failed after {Duration}ms", stopwatch.ElapsedMilliseconds);
throw;
}
}
public void RecordCustomMetric(string name, double value, Dictionary<string, string> labels = null)
{
try
{
var metric = Metrics.CreateGauge($"tusklang_custom_{name}", $"Custom metric: {name}", new GaugeConfiguration
{
LabelNames = labels?.Keys.ToArray() ?? new string[0]
});
if (labels != null)
{
metric.WithLabels(labels.Values.ToArray()).Set(value);
}
else
{
metric.Set(value);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to record custom metric: {Name}", name);
}
}
}
Prometheus TSK Configuration
prometheus-integration.tsk - Prometheus integration
$prometheus_endpoint: @env("PROMETHEUS_ENDPOINT", "http://localhost:9090")
$metrics_interval: @env("METRICS_INTERVAL", "15s")[prometheus]
endpoint: $prometheus_endpoint
interval: $metrics_interval
job_name: @env("PROMETHEUS_JOB_NAME", "tusklang")
instance_name: @env("PROMETHEUS_INSTANCE_NAME", "tusklang-app")
[metrics]
System metrics
cpu_usage: @prometheus.query("system_cpu_usage_percent")
memory_usage: @prometheus.query("system_memory_usage_percent")
requests_per_second: @prometheus.query("system_requests_per_second")
error_rate: @prometheus.query("system_error_rate")Configuration metrics
config_parses: @prometheus.query("tusklang_configuration_parses_total")
config_parse_duration: @prometheus.query("tusklang_configuration_parse_duration_seconds")
config_size: @prometheus.query("tusklang_configuration_size_bytes")
config_errors: @prometheus.query("tusklang_configuration_errors_total")Custom metrics
custom_metrics {
user_count: @prometheus.query("custom_user_count")
order_count: @prometheus.query("custom_order_count")
revenue: @prometheus.query("custom_revenue")
}[alerts]
Alert rules
high_cpu: @if(@metrics.cpu_usage > 80, true, false)
high_memory: @if(@metrics.memory_usage > 85, true, false)
high_error_rate: @if(@metrics.error_rate > 0.05, true, false)
low_requests: @if(@metrics.requests_per_second < 10, true, false)[monitoring]
Monitoring configuration
enabled: true
scrape_interval: "15s"
evaluation_interval: "15s"
alertmanager_url: @env("ALERTMANAGER_URL", "http://localhost:9093")
🎯 Integration Best Practices
1. Error Handling
- ✅ Graceful degradation - Handle integration failures gracefully - ✅ Retry logic - Implement retry mechanisms for transient failures - ✅ Circuit breakers - Prevent cascading failures - ✅ Fallback values - Provide fallback configuration when integrations fail2. Security
- ✅ Secure credentials - Use secure storage for API keys and secrets - ✅ Encryption - Encrypt sensitive data in transit and at rest - ✅ Authentication - Implement proper authentication for all integrations - ✅ Authorization - Control access to integration endpoints3. Performance
- ✅ Caching - Cache integration responses to improve performance - ✅ Connection pooling - Reuse connections for better efficiency - ✅ Async operations - Use async/await for non-blocking operations - ✅ Rate limiting - Respect API rate limits4. Monitoring
- ✅ Metrics collection - Collect metrics for all integrations - ✅ Health checks - Monitor integration health - ✅ Alerting - Set up alerts for integration failures - ✅ Logging - Comprehensive logging for debugging🎉 You're Ready!
You've mastered TuskLang integrations! You can now:
- ✅ Connect to databases - PostgreSQL, MySQL, MongoDB, Redis - ✅ Integrate with cloud services - AWS, Azure, Google Cloud - ✅ Connect to APIs - REST APIs, GraphQL, webhooks - ✅ Monitor systems - Prometheus, Grafana, custom metrics - ✅ Handle enterprise systems - LDAP, Active Directory, SSO - ✅ Build comprehensive integrations - Multi-service orchestration
🔥 What's Next?
Ready for security and enterprise solutions? Explore:
1. Security Deep Dive - Advanced security patterns 2. Enterprise Solutions - Enterprise-grade patterns 3. Deployment Strategies - Production deployment
---
"We don't bow to any king" - Your integrations, your connectivity, your power.
Connect everything with confidence! 🔗