Skip to content

Commit

Permalink
Early spikes on event hubs and openai support.
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanGiles committed Jul 5, 2024
1 parent 1eec5c2 commit 570c5d3
Show file tree
Hide file tree
Showing 16 changed files with 389 additions and 0 deletions.
23 changes: 23 additions & 0 deletions aspire4j/aspire4j-extensions-azure-eventhubs/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.microsoft.aspire</groupId>
<artifactId>aspire4j-sdk-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>aspire4j-extensions-azure-eventhubs</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>com.microsoft.aspire</groupId>
<artifactId>aspire4j</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.microsoft.aspire.extensions.azure.storage;

import com.microsoft.aspire.DistributedApplication;
import com.microsoft.aspire.Extension;
import com.microsoft.aspire.extensions.azure.storage.resources.AzureEventHubsResource;

public class AzureEventHubsExtension implements Extension {

@Override
public String getName() {
return "Azure Event Hubs";
}

@Override
public String getDescription() {
return "Provides resources for Azure Event Hubs";
}

/**
* Adds an Azure Event Hubs Namespace resource to the application model. This resource can be used to create Event
* Hub resources.
* @param name
* @return
*/
public AzureEventHubsResource addAzureEventHubs(String name) {
return DistributedApplication.getInstance().addResource(new AzureEventHubsResource(name));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.microsoft.aspire.extensions.azure.storage.resources;

import com.microsoft.aspire.DistributedApplication;
import com.microsoft.aspire.resources.AzureBicepResource;
import com.microsoft.aspire.resources.ResourceType;
import com.microsoft.aspire.resources.properties.EndpointReference;
import com.microsoft.aspire.resources.traits.ResourceWithEndpoints;
import com.microsoft.aspire.utils.templates.TemplateEngine;

import java.nio.file.Path;
import java.util.List;
import java.util.Map;

public class AzureEventHubsResource extends AzureBicepResource<AzureEventHubsResource>
implements ResourceWithEndpoints<AzureEventHubsResource> {

public AzureEventHubsResource(String name) {
super(name);
}

// public AzureEventHubsResource addEventHub(String name) {
// return DistributedApplication.getInstance().addValue(new AzureEventHubsResource(name, this));
// }

@Override
public List<EndpointReference> getEndpoints() {
// TODO how do I know which endpoints are available?
return List.of();
}

@Override
public List<TemplateFileOutput> processTemplate(Path outputPath) {
final String templatePath = "/templates/bicep/";
final String outputRootPath = "";
List<TemplateDescriptor> templateFiles = TemplateDescriptorsBuilder.begin(templatePath, outputRootPath)
.with("eventhubns.module.bicep", "${name}.module.bicep")
.build();

List<TemplateFileOutput> templateOutput = TemplateEngine.process(AzureEventHubsResource.class, templateFiles, Map.of(
"name", getName()
));

// we know that we need to get the output filename from the first element, and set that as the path
// FIXME we need a better way of determining the output path of the template
withPath(templateOutput.get(0).filename());

return templateOutput;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import com.microsoft.aspire.extensions.azure.storage.AzureEventHubsExtension;

module com.microsoft.aspire.extensions.azure.eventhubs {
requires transitive com.microsoft.aspire;

exports com.microsoft.aspire.extensions.azure.storage;
exports com.microsoft.aspire.extensions.azure.storage.resources;

opens com.microsoft.aspire.extensions.azure.storage to org.hibernate.validator, com.fasterxml.jackson.databind;
opens com.microsoft.aspire.extensions.azure.storage.resources to com.fasterxml.jackson.databind, org.hibernate.validator;

// We conditionally open up the template files to the apphost, so it can write them out
opens templates.bicep to com.microsoft.aspire;

provides com.microsoft.aspire.Extension with AzureEventHubsExtension;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
targetScope = 'resourceGroup'

@description('')
param location string = resourceGroup().location

@description('')
param sku string = 'Standard'

@description('')
param principalId string

@description('')
param principalType string


resource eventHubsNamespace_wORIGuvCQ 'Microsoft.EventHub/namespaces@2021-11-01' = {
name: toLower(take('eventhubns${r"${uniqueString(resourceGroup().id)"}}', 24))
location: location
tags: {
'aspire-resource-name': 'eventhubns'
}
sku: {
name: sku
}
properties: {
}
}

resource roleAssignment_2so8CKuFt 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: eventHubsNamespace_wORIGuvCQ
name: guid(eventHubsNamespace_wORIGuvCQ.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec'))
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec')
principalId: principalId
principalType: principalType
}
}

resource eventHub_4BpPMTltx 'Microsoft.EventHub/namespaces/eventhubs@2021-11-01' = {
parent: eventHubsNamespace_wORIGuvCQ
name: 'hub'
location: location
properties: {
}
}

output eventHubsEndpoint string = eventHubsNamespace_wORIGuvCQ.properties.serviceBusEndpoint
23 changes: 23 additions & 0 deletions aspire4j/aspire4j-extensions-azure-openai/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.microsoft.aspire</groupId>
<artifactId>aspire4j-sdk-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>aspire4j-extensions-azure-openai</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>com.microsoft.aspire</groupId>
<artifactId>aspire4j</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.microsoft.aspire.extensions.azure.openai;

import com.microsoft.aspire.DistributedApplication;
import com.microsoft.aspire.Extension;
import com.microsoft.aspire.extensions.azure.openai.resources.AzureOpenAIResource;

public class AzureOpenAIExtension implements Extension {

@Override
public String getName() {
return "Azure OpenAI";
}

@Override
public String getDescription() {
return "Provides resources for Azure OpenAI";
}

public AzureOpenAIResource addAzureOpenAI(String name) {
return DistributedApplication.getInstance().addResource(new AzureOpenAIResource(name));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.microsoft.aspire.extensions.azure.openai.resources;

/**
* Represents an Azure OpenAI Deployment.
*/
public record AzureOpenAIDeployment(
String name, String modelName, String modelVersion, String skuName, int skuCapacity) {

// Static factory method for creating an instance with some default values
public static AzureOpenAIDeployment using(String name, String modelName, String modelVersion) {
return using(name, modelName, modelVersion, "Standard", 1);
}

public static AzureOpenAIDeployment using(String name, String modelName, String modelVersion, String skuName, int skuCapacity) {
return new AzureOpenAIDeployment(name, modelName, modelVersion, skuName, skuCapacity);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.microsoft.aspire.extensions.azure.openai.resources;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.microsoft.aspire.resources.AzureBicepResource;
import com.microsoft.aspire.resources.properties.EndpointReference;
import com.microsoft.aspire.resources.traits.ResourceWithConnectionString;
import com.microsoft.aspire.resources.traits.ResourceWithEndpoints;
import com.microsoft.aspire.utils.templates.TemplateEngine;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class AzureOpenAIResource extends AzureBicepResource<AzureOpenAIResource>
implements ResourceWithEndpoints<AzureOpenAIResource>,
ResourceWithConnectionString<AzureOpenAIResource> {

@JsonIgnore
private final List<AzureOpenAIDeployment> deployments;

public AzureOpenAIResource(String name) {
super(name);
this.deployments = new ArrayList<>();
}

// TODO the actual intent of this deployment list is to properly write out the deployment resources in the bicep
// template. For now we are not doing that, and simply using a pre-baked bicep template.
public AzureOpenAIResource withDeployment(AzureOpenAIDeployment deployment) {
this.deployments.add(deployment);
return this;
}

@Override
public List<EndpointReference> getEndpoints() {
// TODO how do I know which endpoints are available?
return List.of();
}

@Override
public List<TemplateFileOutput> processTemplate(Path outputPath) {
final String templatePath = "/templates/openai/bicep/";
final String outputRootPath = "";
List<TemplateDescriptor> templateFiles = TemplateDescriptorsBuilder.begin(templatePath, outputRootPath)
.with("openai.module.bicep", "${name}.module.bicep")
.build();

List<TemplateFileOutput> templateOutput = TemplateEngine.process(AzureOpenAIResource.class, templateFiles, Map.of(
"name", getName()
));

// we know that we need to get the output filename from the first element, and set that as the path
// FIXME we need a better way of determining the output path of the template
withPath(templateOutput.get(0).filename());

return templateOutput;
}

@Override
public String getConnectionStringEnvironmentVariable() {
return "connectionString";
}

@Override
public String getValue() {
return getName() + ".outputs.connectionString";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import com.microsoft.aspire.extensions.azure.openai.AzureOpenAIExtension;

module com.microsoft.aspire.extensions.azure.openai {
requires transitive com.microsoft.aspire;

exports com.microsoft.aspire.extensions.azure.openai;
exports com.microsoft.aspire.extensions.azure.openai.resources;

opens com.microsoft.aspire.extensions.azure.openai to org.hibernate.validator, com.fasterxml.jackson.databind;
opens com.microsoft.aspire.extensions.azure.openai.resources to com.fasterxml.jackson.databind, org.hibernate.validator;

// We conditionally open up the template files to the apphost, so it can write them out
opens templates.openai.bicep to com.microsoft.aspire;

provides com.microsoft.aspire.Extension with AzureOpenAIExtension;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
targetScope = 'resourceGroup'

@description('')
param location string = resourceGroup().location

@description('')
param principalId string

@description('')
param principalType string


resource cognitiveServicesAccount_wXAGTFUId 'Microsoft.CognitiveServices/accounts@2023-05-01' = {
name: toLower(take('openai${r"${uniqueString(resourceGroup().id)}"}', 24))
location: location
kind: 'OpenAI'
sku: {
name: 'S0'
}
properties: {
customSubDomainName: toLower(take(concat('openai', uniqueString(resourceGroup().id)), 24))
publicNetworkAccess: 'Enabled'
}
}

resource roleAssignment_Hsk8rxWY8 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: cognitiveServicesAccount_wXAGTFUId
name: guid(cognitiveServicesAccount_wXAGTFUId.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a001fd3d-188f-4b5d-821b-7da978bf7442'))
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a001fd3d-188f-4b5d-821b-7da978bf7442')
principalId: principalId
principalType: principalType
}
}

resource cognitiveServicesAccountDeployment_hU1MaqMLH 'Microsoft.CognitiveServices/accounts/deployments@2023-05-01' = {
parent: cognitiveServicesAccount_wXAGTFUId
name: 'gpt-35-turbo'
sku: {
name: 'Standard'
capacity: 1
}
properties: {
model: {
format: 'OpenAI'
name: 'gpt-35-turbo'
version: '0613'
}
}
}

output connectionString string = 'Endpoint=${r"${cognitiveServicesAccount_wXAGTFUId.properties.endpoint}"}'
10 changes: 10 additions & 0 deletions aspire4j/aspire4j-extensions-azure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,20 @@
<version>1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>com.microsoft.aspire</groupId>
<artifactId>aspire4j-extensions-azure-openai</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.microsoft.aspire</groupId>
<artifactId>aspire4j-extensions-azure-storage</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.microsoft.aspire</groupId>
<artifactId>aspire4j-extensions-azure-eventhubs</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Loading

0 comments on commit 570c5d3

Please sign in to comment.