Skip to content

Commit 5092fcc

Browse files
committed
Integrate Azure Blob and update JSON handling
- Updated `ProcessCertDataFile` to include `BlobServiceClient` for Azure Blob Storage operations. - Modified `ProcessCertDataFile` to generate and upload JSON files to "certservice" container. - Switched `ProcessCertServiceFile` to use `CertificationService` for JSON validation and deserialization. - Updated `CreateCertServiceDocument` method in `ProcessCertServiceFile` to use `CertificationService`. - Registered `BlobServiceClient` as a singleton in `Program.cs`. - Updated `azure-project-generator.csproj` to include `JsonSchema.Net` and `JsonSchema.Net.Generation` packages, and removed `Newtonsoft.Json.Schema`. - Renamed `MappedService` to `CertificationService`. - Renamed `SkillMeasured` to `CertificationSkillMeasured`. - Updated `ContentGenerationService` to use `CertificationService` in `GenerateCertServiceContextSentence`. - Updated `JsonValidationService` to use `JsonSchema.Net` for JSON schema validation.
2 parents 6047f69 + c1b6747 commit 5092fcc

File tree

8 files changed

+63
-22
lines changed

8 files changed

+63
-22
lines changed

azure-project-generator/ProcessCertPromptFile.cs renamed to azure-project-generator/ProcessCertDataFile.cs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,32 @@
44
using Microsoft.Extensions.Logging;
55
using Newtonsoft.Json;
66
using OpenAI.Embeddings;
7+
using Azure.Storage.Blobs;
8+
using System.Text;
79

810
namespace azure_project_generator
911
{
10-
public class ProcessCertPromptFile
12+
public class ProcessCertDataFile
1113
{
1214
private readonly ILogger<ProcessCertServiceFile> _logger;
1315
private readonly EmbeddingClient _embeddingClient;
1416
private readonly JsonValidationService _jsonValidationService;
1517
private readonly ContentGenerationService _contentGenerationService;
18+
private readonly BlobServiceClient _blobServiceClient;
1619

17-
public ProcessCertPromptFile(ILogger<ProcessCertServiceFile> logger,
20+
public ProcessCertDataFile(ILogger<ProcessCertServiceFile> logger,
1821
EmbeddingClient embeddingClient,
1922
JsonValidationService jsonValidationService,
20-
ContentGenerationService contentGenerationService)
21-
{
23+
ContentGenerationService contentGenerationService, BlobServiceClient blobServiceClient)
24+
{
2225
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
2326
_embeddingClient = embeddingClient ?? throw new ArgumentNullException(nameof(embeddingClient));
2427
_jsonValidationService = jsonValidationService ?? throw new ArgumentNullException(nameof(jsonValidationService));
2528
_contentGenerationService = contentGenerationService ?? throw new ArgumentNullException(nameof(contentGenerationService));
29+
_blobServiceClient = blobServiceClient ?? throw new ArgumentNullException(nameof(blobServiceClient));
2630
}
2731

28-
[Function(nameof(ProcessCertPromptFile))]
32+
[Function(nameof(ProcessCertDataFile))]
2933
public async Task<CertificationProjectPromptOutput> Run([BlobTrigger("certdata/{name}", Connection = "AzureWebJobsStorage")] string content, string name)
3034
{
3135

@@ -47,6 +51,34 @@ public async Task<CertificationProjectPromptOutput> Run([BlobTrigger("certdata/{
4751
return new CertificationProjectPromptOutput { Document = null, ArchivedContent = null };
4852
}
4953

54+
// create a json file for each service in the certification
55+
56+
foreach (var skill in certification.SkillsMeasured)
57+
{
58+
foreach (var topic in skill.Topics)
59+
{
60+
foreach (var service in topic.Services)
61+
{
62+
var serviceData = new CertificationService
63+
{
64+
CertificationCode = certification.CertificationCode,
65+
CertificationName = certification.CertificationName,
66+
SkillName = skill.Name,
67+
TopicName = topic.TopicName,
68+
ServiceName = service
69+
};
70+
BlobContainerClient blobContainerClient = _blobServiceClient.GetBlobContainerClient("certservice");
71+
var serviceJson = JsonConvert.SerializeObject(serviceData);
72+
var serviceBlobName = $"{certification.CertificationCode}-{serviceData.ServiceName}.json";
73+
74+
BlobClient blobClient = blobContainerClient.GetBlobClient(serviceBlobName);
75+
await blobClient.UploadAsync(new MemoryStream(Encoding.UTF8.GetBytes(serviceJson)), true);
76+
}
77+
}
78+
}
79+
80+
81+
5082
string contextSentence = _contentGenerationService.GenerateCertDataContextSentence(certification);
5183
float[] contentVector = await _contentGenerationService.GenerateEmbeddingsAsync(contextSentence);
5284

azure-project-generator/ProcessCertServiceFile.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ public async Task<CertificationServiceOutput> Run(
3838
return new CertificationServiceOutput { Document = null, ArchivedContent = null };
3939
}
4040

41-
if (!_jsonValidationService.ValidateJsonContent<MappedService>(content))
41+
if (!_jsonValidationService.ValidateJsonContent<CertificationService>(content))
4242
{
4343
return new CertificationServiceOutput { Document = null, ArchivedContent = null };
4444
}
4545

46-
var mappedServiceData = JsonConvert.DeserializeObject<MappedService>(content);
46+
var mappedServiceData = JsonConvert.DeserializeObject<CertificationService>(content);
4747
if (mappedServiceData == null)
4848
{
4949
_logger.LogError("Failed to deserialize content to MappedService.");
@@ -68,7 +68,7 @@ public async Task<CertificationServiceOutput> Run(
6868

6969
// Other methods remain unchanged
7070

71-
private CertificationServiceDocument CreateCertServiceDocument(MappedService data, string contextSentence, float[] contentVector) =>
71+
private CertificationServiceDocument CreateCertServiceDocument(CertificationService data, string contextSentence, float[] contentVector) =>
7272
new CertificationServiceDocument
7373
{
7474
Id = Guid.NewGuid().ToString(),

azure-project-generator/Program.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Azure;
22
using Azure.AI.OpenAI;
3+
using Azure.Storage.Blobs;
34
using azure_project_generator.services;
45
using Microsoft.Azure.Functions.Worker;
56
using Microsoft.Extensions.DependencyInjection;
@@ -19,12 +20,16 @@
1920
string keyFromEnvironment = config["AZURE_OPENAI_API_KEY"];
2021
string endpointFromEnvironment = config["AZURE_OPENAI_API_ENDPOINT"];
2122
string embeddingsDeployment = config["EMBEDDINGS_DEPLOYMENT"];
23+
string azureWebJobsStorage = config["AzureWebJobsStorage"];
2224

2325
if (string.IsNullOrEmpty(keyFromEnvironment) || string.IsNullOrEmpty(endpointFromEnvironment) || string.IsNullOrEmpty(embeddingsDeployment))
2426
{
2527
throw new InvalidOperationException("Required Azure OpenAI configuration is missing.");
2628
}
2729

30+
// Register BlobServiceClient as a singleton
31+
services.AddSingleton(new BlobServiceClient(azureWebJobsStorage));
32+
2833
AzureOpenAIClient azureClient = new(
2934
new Uri(endpointFromEnvironment),
3035
new AzureKeyCredential(keyFromEnvironment));

azure-project-generator/azure-project-generator.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
<PackageReference Include="Azure.Storage.Blobs" Version="12.21.2" />
1717
<PackageReference Include="Azure.Storage.Files.Shares" Version="12.19.1" />
1818
<PackageReference Include="Azure.Storage.Queues" Version="12.19.1" />
19+
<PackageReference Include="JsonSchema.Net" Version="7.2.2" />
20+
<PackageReference Include="JsonSchema.Net.Generation" Version="4.5.0" />
1921
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.23.0" />
2022
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.CosmosDB" Version="4.10.0" />
2123
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
@@ -26,7 +28,6 @@
2628
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.3.0" />
2729
<PackageReference Include="Microsoft.Extensions.Azure" Version="1.7.5" />
2830
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
29-
<PackageReference Include="Newtonsoft.Json.Schema" Version="4.0.1" />
3031
</ItemGroup>
3132
<ItemGroup>
3233
<None Update="host.json">

azure-project-generator/models/MappedService.cs renamed to azure-project-generator/models/CertificationService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace azure_project_generator.models
44
{
5-
public class MappedService
5+
public class CertificationService
66
{
77
[JsonProperty("certificationCode")]
88
public string CertificationCode { get; set; }

azure-project-generator/models/SkillMeasured.cs renamed to azure-project-generator/models/CertificationSkillMeasured.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace azure_project_generator.models
44
{
5-
public class SkillMeasured
5+
public class CertificationSkillMeasured
66
{
77
[Required]
88
public string Name { get; set; }

azure-project-generator/services/ContentGenerationService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public ContentGenerationService(ILogger<ContentGenerationService> logger, Embedd
1616
_embeddingClient = embeddingClient ?? throw new ArgumentNullException(nameof(embeddingClient));
1717
}
1818

19-
public string GenerateCertServiceContextSentence(MappedService data) =>
19+
public string GenerateCertServiceContextSentence(CertificationService data) =>
2020
$"The {data.CertificationCode} {data.CertificationName} certification includes the skill of {data.SkillName}. Within this skill, there is a focus on the topic of {data.TopicName}, particularly through the use of the service {data.ServiceName}.";
2121

2222
public string GenerateCertDataContextSentence(Certification certificationDocument)

azure-project-generator/services/JsonValidationService.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
using Json.Schema;
2+
using Json.Schema.Generation;
3+
using Json.Schema.Serialization;
14
using Microsoft.Extensions.Logging;
25
using Newtonsoft.Json.Linq;
3-
using Newtonsoft.Json.Schema;
4-
using Newtonsoft.Json.Schema.Generation;
56
using System.Text.Json;
7+
using System.Text.Json.Nodes;
8+
69

710
namespace azure_project_generator.services
811
{
@@ -20,25 +23,25 @@ public bool ValidateJsonContent<T>(string content)
2023
{
2124
try
2225
{
23-
var generator = new JSchemaGenerator();
24-
JSchema schema = generator.Generate(typeof(T));
26+
JsonSchemaBuilder jsonSchemaBuilder = new JsonSchemaBuilder();
27+
var schema1 = jsonSchemaBuilder.FromType<T>().Build();
28+
29+
var result = schema1.Evaluate(JsonNode.Parse(content));
2530

26-
JToken jsonContent = JToken.Parse(content);
27-
bool isValid = jsonContent.IsValid(schema, out IList<string> messages);
2831

29-
if (!isValid)
32+
if (!result.IsValid)
3033
{
31-
foreach (var message in messages)
34+
foreach (var error in result.Errors)
3235
{
33-
_logger.LogError($"Schema validation error: {message}");
36+
_logger.LogError($"Schema validation error: {error.Key} + \": \" + {error.Value}");
3437
}
3538
}
3639
else
3740
{
3841
_logger.LogInformation("JSON content is valid against the schema.");
3942
}
4043

41-
return isValid;
44+
return result.IsValid;
4245
}
4346
catch (JsonException ex)
4447
{

0 commit comments

Comments
 (0)