Skip to content
This repository has been archived by the owner on Jul 6, 2022. It is now read-only.

Adding Text Analytics module (Cognitive Services) #557

Merged
merged 13 commits into from
Sep 28, 2018
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 56 additions & 0 deletions docs/modules/textanalytics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# [Azure Text Analytics](https://azure.microsoft.com/en-us/services/cognitive-services/text-analytics/)

_Note: This module is EXPERIMENTAL and future releases may break the API._

## Services & Plans

### Service: azure-text-analytics

| Plan Name | Description |
|-----------|-------------|
| `free` | Free with 5,000 monthly transactions and no overage. |
| `standard-s0` | 25,000 monthly transactions and 3.00 per 1,000 overage. |
| `standard-s1` | 100,000 monthly transactions and 2.50 per 1,000 overage. |
| `standard-s2` | 500,000 monthly transactions and 2.00 per 1,000 overage. |
| `standard-s3` | 2,500,000 monthly transactions and 1.00 per 1,000 overage. |
| `standard-s4` | 10,000,000 monthly transactions and .50 per 1,000 overage. |

#### Behaviors

##### Provision

Provisions a new text analytics API.

###### Provisioning Parameters

| Parameter Name | Type | Description | Required | Default Value |
|----------------|------|-------------|----------|---------------|
| `location` | `string` | The Azure region in which to provision applicable resources. | Required _unless_ an administrator has configured the broker itself with a default location. | The broker's default location, if configured. |
| `resourceGroup` | `string` | The (new or existing) resource group with which to associate new resources. | N | If an administrator has configured the broker itself with a default resource group and node is specified, that default will be applied, otherwise, a new resource group will be created with a UUID as its name. |
| `tags` | `map[string]string` | Tags to be applied to new resources, specified as key/value pairs. | N | Tags (even if none are specified) are automatically supplemented with `heritage: open-service-broker-azure`. |

##### Bind

Returns the API address and access key.

###### Binding Parameters

This binding operation does not support any parameters.

###### Credentials

Binding returns the following connection details:

| Field Name | Type | Description |
|------------|------|-------------|
| `textAnalyticsEndpoint` | `string` | The text analytics API endpoint address. |
| `textAnalyticsKey` | `string` | The text analytics API access key. |
| `textAnalyticsName` | `string` | The name of the text analytics API. |

##### Unbind

Does nothing.

##### Deprovision

Deletes the text analytics API.
10 changes: 10 additions & 0 deletions pkg/boot/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"time"

cognitiveSDK "github.com/Azure/azure-sdk-for-go/services/cognitiveservices/mgmt/2017-04-18/cognitiveservices"
cosmosSDK "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb"
eventHubSDK "github.com/Azure/azure-sdk-for-go/services/eventhub/mgmt/2017-04-01/eventhub"
keyVaultSDK "github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2016-10-01/keyvault"
Expand All @@ -28,6 +29,7 @@ import (
"github.com/Azure/open-service-broker-azure/pkg/services/rediscache"
"github.com/Azure/open-service-broker-azure/pkg/services/servicebus"
"github.com/Azure/open-service-broker-azure/pkg/services/storage"
"github.com/Azure/open-service-broker-azure/pkg/services/textanalytics"
"github.com/Azure/open-service-broker-azure/pkg/version"
)

Expand Down Expand Up @@ -65,6 +67,13 @@ func getModules(
resourceDeploymentsClient,
)

cognitiveClient := cognitiveSDK.NewAccountsClientWithBaseURI(
azureConfig.Environment.ResourceManagerEndpoint,
azureSubscriptionID,
)
cognitiveClient.Authorizer = authorizer
cognitiveClient.UserAgent = getUserAgent(cognitiveClient.Client)

cosmosdbAccountsClient := cosmosSDK.NewDatabaseAccountsClientWithBaseURI(
azureConfig.Environment.ResourceManagerEndpoint,
azureSubscriptionID,
Expand Down Expand Up @@ -191,6 +200,7 @@ func getModules(
),
cosmosdb.New(armDeployer, cosmosdbAccountsClient),
storage.New(armDeployer, storageAccountsClient),
textanalytics.New(armDeployer, cognitiveClient),
}

return modules, nil
Expand Down
44 changes: 44 additions & 0 deletions pkg/services/textanalytics/arm_template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package textanalytics

// nolint: lll
var armTemplateBytes = []byte(`
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"tags": {
"type": "object"
}
},
"variables": {
"cognitiveservicesid": "[concat(resourceGroup().id,'/providers/','Microsoft.CognitiveServices/accounts/','{{ .name }}')]"
},
"resources": [{
"type": "Microsoft.CognitiveServices/accounts",
"sku": {
"name": "{{ .tier }}"
},
"kind": "TextAnalytics",
"name": "{{ .name }}",
"apiVersion": "2016-02-01-preview",
"location": "{{ .location }}",
"scale": null,
"properties": {},
"dependsOn": []
}],
"outputs": {
"cognitivekey": {
"type": "string",
"value": "[listKeys(variables('cognitiveservicesid'),'2016-02-01-preview').key1]"
},
"endpoint": {
"type": "string",
"value": "[reference(variables('cognitiveservicesid'),'2016-02-01-preview').endpoint]"
},
"name": {
"type": "string",
"value": "{{ .name }}"
}
}
}
`)
24 changes: 24 additions & 0 deletions pkg/services/textanalytics/bind.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package textanalytics

import (
"github.com/Azure/open-service-broker-azure/pkg/service"
)

func (s *serviceManager) Bind(
service.Instance,
service.BindingParameters,
) (service.BindingDetails, error) {
return nil, nil
}

func (s *serviceManager) GetCredentials(
instance service.Instance,
_ service.Binding,
) (service.Credentials, error) {
dt := instance.Details.(*instanceDetails)
return &credentials{
TextAnalyticsKey: dt.TextAnalyticsKey,
Endpoint: dt.Endpoint,
TextAnalyticsName: dt.TextAnalyticsName,
}, nil
}
138 changes: 138 additions & 0 deletions pkg/services/textanalytics/catalog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package textanalytics

import "github.com/Azure/open-service-broker-azure/pkg/service"

func (m *module) GetCatalog() (service.Catalog, error) {
return service.NewCatalog([]service.Service{
service.NewService(
service.ServiceProperties{
ID: "8f6c848a-4ce1-4a69-9248-63545d3e7e9c",
Name: "azure-text-analytics",
Description: "Azure Text Analytics (Experimental)",
Metadata: service.ServiceMetadata{
DisplayName: "Azure Text Analytics",
ImageURL: "https://azure.microsoft.com/svghandler/text-analytics/" +
"?width=200",
LongDescription: "Infuse your apps, websites and bots with " +
"intelligent algorithms to see, hear, speak, understand and " +
"interpret your user needs through natural methods of communication." +
" (Experimental)",
DocumentationURL: "https://docs.microsoft.com/en-us/azure/" +
"cognitive-services/text-analytics/",
SupportURL: "https://azure.microsoft.com/en-us/support/",
},
Bindable: true,
Tags: []string{"Azure", "Cognitive", "Text Analytics", "Analytics"},
},
m.serviceManager,
service.NewPlan(service.PlanProperties{
ID: "d5a0f91f-10da-42fc-b792-656a616d9ec2",
Name: "free",
Description: "Text Analytics Free Tier - max 5,000" +
" transactions per 30 days.",
Free: true,
Extended: map[string]interface{}{
"textAnalyticsSku": "F0",
},
Metadata: service.ServicePlanMetadata{
DisplayName: "Free Tier",
},
Schemas: service.PlanSchemas{
ServiceInstances: service.InstanceSchemas{
ProvisioningParametersSchema: generateProvisioningParamsSchema(),
},
},
}),
service.NewPlan(service.PlanProperties{
ID: "7f49713b-2689-4c66-bac9-85a024c0fb9e",
Name: "standard-s0",
Description: "Text Analytics Standard 0 Tier - max 25,000" +
" transactions per 30 days.",
Free: true,
Extended: map[string]interface{}{
"textAnalyticsSku": "S0",
},
Metadata: service.ServicePlanMetadata{
DisplayName: "Standard 0 Tier",
},
Schemas: service.PlanSchemas{
ServiceInstances: service.InstanceSchemas{
ProvisioningParametersSchema: generateProvisioningParamsSchema(),
},
},
}),
service.NewPlan(service.PlanProperties{
ID: "55575612-482b-4260-b67e-69be36d83a54",
Name: "standard-s1",
Description: "Text Analytics Standard 1 Tier - max 100,000" +
" transactions per 30 days.",
Free: true,
Extended: map[string]interface{}{
"textAnalyticsSku": "S1",
},
Metadata: service.ServicePlanMetadata{
DisplayName: "Standard 1 Tier",
},
Schemas: service.PlanSchemas{
ServiceInstances: service.InstanceSchemas{
ProvisioningParametersSchema: generateProvisioningParamsSchema(),
},
},
}),
service.NewPlan(service.PlanProperties{
ID: "76bc6a2f-1364-4ef2-8037-d7cfff48f3b6",
Name: "standard-s2",
Description: "Text Analytics Standard 2 Tier - max 500,000" +
" transactions per 30 days.",
Free: true,
Extended: map[string]interface{}{
"textAnalyticsSku": "S2",
},
Metadata: service.ServicePlanMetadata{
DisplayName: "Standard 2 Tier",
},
Schemas: service.PlanSchemas{
ServiceInstances: service.InstanceSchemas{
ProvisioningParametersSchema: generateProvisioningParamsSchema(),
},
},
}),
service.NewPlan(service.PlanProperties{
ID: "1d9a9e7c-80ac-4f23-aabe-876125541f59",
Name: "standard-s3",
Description: "Text Analytics Standard 3 Tier - max 2,500,000" +
" transactions per 30 days.",
Free: true,
Extended: map[string]interface{}{
"textAnalyticsSku": "S3",
},
Metadata: service.ServicePlanMetadata{
DisplayName: "Standard 3 Tier",
},
Schemas: service.PlanSchemas{
ServiceInstances: service.InstanceSchemas{
ProvisioningParametersSchema: generateProvisioningParamsSchema(),
},
},
}),
service.NewPlan(service.PlanProperties{
ID: "b9db834d-1350-4c50-adaf-f1e59efa2381",
Name: "standard-s4",
Description: "Text Analytics Standard 4 Tier - max 10,000,000" +
" transactions per 30 days.",
Free: true,
Extended: map[string]interface{}{
"textAnalyticsSku": "S4",
},
Metadata: service.ServicePlanMetadata{
DisplayName: "Standard 4 Tier",
},
Schemas: service.PlanSchemas{
ServiceInstances: service.InstanceSchemas{
ProvisioningParametersSchema: generateProvisioningParamsSchema(),
},
},
}),
),
}), nil
}
49 changes: 49 additions & 0 deletions pkg/services/textanalytics/deprovision.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package textanalytics

import (
"context"
"fmt"

"github.com/Azure/open-service-broker-azure/pkg/service"
)

func (s *serviceManager) GetDeprovisioner(
service.Plan,
) (service.Deprovisioner, error) {
return service.NewDeprovisioner(
service.NewDeprovisioningStep("deleteARMDeployment", s.deleteARMDeployment),
service.NewDeprovisioningStep("deleteContainer", s.deleteContainer),
)
}

func (s *serviceManager) deleteARMDeployment(
_ context.Context,
instance service.Instance,
) (service.InstanceDetails, error) {
dt := instance.Details.(*instanceDetails)
if err := s.armDeployer.Delete(
dt.ARMDeploymentName,
instance.ProvisioningParameters.GetString("resourceGroup"),
); err != nil {
return nil, fmt.Errorf("error deleting ARM deployment: %s", err)
}
return instance.Details, nil
}

func (s *serviceManager) deleteContainer(
ctx context.Context,
instance service.Instance,
) (service.InstanceDetails, error) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
dt := instance.Details.(*instanceDetails)
_, err := s.congnitiveClient.Delete(
ctx,
instance.ProvisioningParameters.GetString("resourceGroup"),
dt.TextAnalyticsName,
)
if err != nil {
return nil, fmt.Errorf("error deleting Cognitive Services account: %s", err)
}
return instance.Details, nil
}
29 changes: 29 additions & 0 deletions pkg/services/textanalytics/plan_schemas.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package textanalytics

import (
"github.com/Azure/open-service-broker-azure/pkg/azure"
"github.com/Azure/open-service-broker-azure/pkg/service"
)

func generateProvisioningParamsSchema() service.InputParametersSchema {
return service.InputParametersSchema{
RequiredProperties: []string{"location", "resourceGroup"},
PropertySchemas: map[string]service.PropertySchema{
"location": &service.StringPropertySchema{
Title: "Location",
Description: "The Azure region in which to provision" +
" applicable resources.",
CustomPropertyValidator: azure.LocationValidator,
},
"resourceGroup": &service.StringPropertySchema{
Title: "Resource group",
Description: "The (new or existing) resource group with which" +
" to associate new resources.",
},
"name": &service.StringPropertySchema{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why make parameter name user-specified? In other modules, the name of the server, database, and so on, is generated randomly and is not configurable for users. I'm not familiar with textanalytics, please tell me if there is any special concern to do this. If not, could you make name randomly generated just like other modules?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this @norshtein . The parameter was actually unused and has been removed.

Title: "Name",
Description: "Text Analytics API name.",
},
},
}
}
Loading