Skip to content
This repository has been archived by the owner on May 5, 2023. It is now read-only.

contentKeyPolicies.createOrUpdate parameters structure #2942

Closed
aaani opened this issue Jun 4, 2018 · 10 comments
Closed

contentKeyPolicies.createOrUpdate parameters structure #2942

aaani opened this issue Jun 4, 2018 · 10 comments
Labels
customer-reported This issue was reported by a customer.

Comments

@aaani
Copy link

aaani commented Jun 4, 2018

I am trying to invoke contentKeyPolicies.createOrUpdate and I can't figure out from the docs what the structure of parameters.options look like. This tells me it's an array of the Key Policy options but I can't find what Key Policy options look like.

This is what I have so far:

const AzureMediaServices = require("azure-arm-mediaservices").AzureMediaServices;
const AzureMediaServicesModels = require("azure-arm-mediaservices").AzureMediaServicesModels;

.
.
.

const azureMediaServicesClient = new AzureMediaServices(credentials, "<MASKED>");

const contentKeyPolicyPlain = {options: [{
    configuration: {
        responseCustomData: null,
        licenses: [{
            allowTestDevices: true,
            contentKeyLocation: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyContentEncryptionKeyFromHeader(),
            contentType: 'UltraVioletDownload',
            licenseType: 'NonPersistent'
        }]
    },
    restriction: new AzureMediaServicesModels.ContentKeyPolicyOpenRestriction()
}]};

return azureMediaServicesClient.contentKeyPolicies.createOrUpdate("<MASKED>", "<MASKED>", "test-policy-1", contentKeyPolicyPlain)
    .then(function (result) {
        console.log("The result is:");
        console.log(result);
    }).catch(function (err) {
        console.error(err);
    });

And I am getting the following error:

Error: A type named 'configuration' could not be resolved by the model. When a model is available, each type name must resolve to a valid type.

with HTTP 400

Please advise.

@amarzavery
Copy link
Contributor

@johndeu, @BrianBlum - Can one of you please take a look at this issue?

@BrianBlum
Copy link

BrianBlum commented Jun 5, 2018 via email

@johndeu
Copy link

johndeu commented Jun 5, 2018

@quintinb Is this a Swagger documentation gap issue or other issue on ContentKeyPolicies?

@johndeu
Copy link

johndeu commented Jun 5, 2018

We need to provide some basic pointers or explanation of what the Key Policy options actually are... I assume this gets complicated as it points to several DRM providers documentation pages which may not be public (like Apple FairPlay, and PlayReady)

@amarzavery
Copy link
Contributor

@aaani - I agree we need to do a better job at documenting stuff. Some of this can be improved by providing better description in the Swagger specification of the REST APIs (We autogenerate our sdks from the swagger specs).

We also need to do a better job at generating source code docs for the SDK. For now you can refer to the typescript type definitions for the model over here.

I would recommend using vscode as the IDE. It provides an awesome experience if you are writing your app in typescript. However, when you are writing your app in Javascript, it will still make a decent attempt at providing intellisense and documentation.

@aaani
Copy link
Author

aaani commented Jun 5, 2018

@amarzavery I did follow the type definitions to come up with the example that I presented above. Would it possible for you to reach out the QA person who tested this? Maybe they can share some examples?

For what it's worth, some other attempts that I made:

  1. With parameter as a complex object:
const contentKeyPolicyPlayReadyLicense = new AzureMediaServicesModels.ContentKeyPolicyPlayReadyLicense({
    allowTestDevices: true,
    contentKeyLocation: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyContentEncryptionKeyFromHeader(),
    contentType: 'UltraVioletDownload',
    licenseType: 'NonPersistent',
    playRight: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyPlayRight({
        imageConstraintForAnalogComponentVideoRestriction: true,
        explicitAnalogTelevisionOutputRestriction: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyExplicitAnalogTelevisionRestriction(true, 2),
        allowPassingVideoContentToUnknownOutput: 'Allowed'
    })
});

const contentKeyPolicyPlayReadyConfiguration = new AzureMediaServicesModels.ContentKeyPolicyPlayReadyConfiguration({
    responseCustomData: null,
    licenses: [contentKeyPolicyPlayReadyLicense]
});
const contentKeyPolicyOption = new AzureMediaServicesModels.ContentKeyPolicyOption({
    configuration: contentKeyPolicyPlayReadyConfiguration,
    restriction: new AzureMediaServicesModels.ContentKeyPolicyOpenRestriction()
});
const contentKeyPolicy = new AzureMediaServicesModels.ContentKeyPolicy({options: [contentKeyPolicyOption]});

return azureMediaServicesClient.contentKeyPolicies.createOrUpdate("<MASKED>", "<MASKED>", "test-policy-1", contentKeyPolicy)
    .then(function (result) {
        console.log("The result is:");
        console.log(result);
    }).catch(function (err) {
        console.error(err);
    });

Got error:

Error: Error "options" cannot be null or undefined in "parameters"." occurred in serializing the payload - {}.

I believe it fails before it issues a HTTP Request in this case.

  1. With parameters.options key excluded from the complex object (based on the above error indicating parameters are empty)
const contentKeyPolicyPlayReadyLicense = new AzureMediaServicesModels.ContentKeyPolicyPlayReadyLicense({
    allowTestDevices: true,
    contentKeyLocation: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyContentEncryptionKeyFromHeader(),
    contentType: 'UltraVioletDownload',
    licenseType: 'NonPersistent',
    playRight: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyPlayRight({
        imageConstraintForAnalogComponentVideoRestriction: true,
        explicitAnalogTelevisionOutputRestriction: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyExplicitAnalogTelevisionRestriction(true, 2),
        allowPassingVideoContentToUnknownOutput: 'Allowed'
    })
});

const contentKeyPolicyPlayReadyConfiguration = new AzureMediaServicesModels.ContentKeyPolicyPlayReadyConfiguration({
    responseCustomData: null,
    licenses: [contentKeyPolicyPlayReadyLicense]
});
const contentKeyPolicyOption = new AzureMediaServicesModels.ContentKeyPolicyOption({
    configuration: contentKeyPolicyPlayReadyConfiguration,
    restriction: new AzureMediaServicesModels.ContentKeyPolicyOpenRestriction()
});

return azureMediaServicesClient.contentKeyPolicies.createOrUpdate("<MASKED>", "<MASKED>", "test-policy-1", {options: [contentKeyPolicyOption]})
    .then(function (result) {
        console.log("The result is:");
        console.log(result);
    }).catch(function (err) {
        console.error(err);
    });

Got error:

Error: Error "configuration" cannot be null or undefined in "parameters.properties.options[0]"." occurred in serializing the payload - {
  "options": [
    {}
  ]
}

I believe it fails before it issues a HTTP Request in this case as well.

  1. With parameters.options.configuration and parameters.options.restriction excluded from the complex objects. Again (based on the above error indicating options is empty):
const contentKeyPolicyPlayReadyLicense = new AzureMediaServicesModels.ContentKeyPolicyPlayReadyLicense({
    allowTestDevices: true,
    contentKeyLocation: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyContentEncryptionKeyFromHeader(),
    contentType: 'UltraVioletDownload',
    licenseType: 'NonPersistent',
    playRight: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyPlayRight({
        imageConstraintForAnalogComponentVideoRestriction: true,
        explicitAnalogTelevisionOutputRestriction: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyExplicitAnalogTelevisionRestriction(true, 2),
        allowPassingVideoContentToUnknownOutput: 'Allowed'
    })
});

const contentKeyPolicyPlayReadyConfiguration = new AzureMediaServicesModels.ContentKeyPolicyPlayReadyConfiguration({
    responseCustomData: null,
    licenses: [contentKeyPolicyPlayReadyLicense]
});

return azureMediaServicesClient.contentKeyPolicies.createOrUpdate("<MASKED>", "<MASKED>", "test-policy-1", {options: [{
    configuration: contentKeyPolicyPlayReadyConfiguration,
    restriction: new AzureMediaServicesModels.ContentKeyPolicyOpenRestriction()
}]}).then(function (result) {
    console.log("The result is:");
    console.log(result);
}).catch(function (err) {
    console.error(err);
});

Got error:

Error: A type named 'configuration' could not be resolved by the model. When a model is available, each type name must resolve to a valid type.

Note: This is the same error as the original example I posted.

  1. With ClearKey Policy
return azureMediaServicesClient.contentKeyPolicies.createOrUpdate("<MASKED>", "<MASKED>", "test-policy-1", {options: [{
    configuration: new AzureMediaServicesModels.ContentKeyPolicyClearKeyConfiguration(),
    restriction: new AzureMediaServicesModels.ContentKeyPolicyOpenRestriction()
}]}).then(function (result) {
    console.log("The result is:");
    console.log(result);
}).catch(function (err) {
    console.error(err);
});

Got error:

Error: A type named 'configuration' could not be resolved by the model. When a model is available, each type name must resolve to a valid type.

Note: This is also the same error as the original example I posted.

@aaani
Copy link
Author

aaani commented Jun 6, 2018

@amarzavery @johndeu @BrianBlum - Gents, any updates about this issue?

@amarzavery
Copy link
Contributor

I have an idea of what is going on. The problem is in the way the objects are being created with new operator for method parameters. That will simply give you empty objects (since those model classes have no properties) and will not serve the purpose.

In JS world, customers like to provide anonymous JSON objects as parameters to the method. Hence the SDK expects you to use {} and populate properties of the object at all the levels.

I do understand that this is a broken experience. We are working on a new TypeScript SDK where we only generate interfaces for models. There are no classes. Hence there will be no way to use the new operator and therefor no confusion.

For polymorphic types, the property marked as discriminator (in this case, odatatype) is a required property and it's value must match what the service expects on the wire. To make matters worse, we don't document the expected value for this property or atleast provide an enum in the TS type definitions that could tell you what the values are.

The way to find the value for the discriminator property is to look at the mapper function in the source code for that model class and use the serializedName of that model as the value for the discriminator property.

For example: The value for odatatype property of ContentKeyPolicyPlayReadyContentEncryptionKeyFromHeader can be found from here.

const AzureMediaServices = require("azure-arm-mediaservices").AzureMediaServices;
const AzureMediaServicesModels = require("azure-arm-mediaservices").AzureMediaServicesModels;

.
.
.

const azureMediaServicesClient = new AzureMediaServices(credentials, "<MASKED>");

const contentKeyPolicyPlain = {options: [{
    configuration: {
        responseCustomData: null,
        licenses: [{
            allowTestDevices: true,
            // This will not help..
            // contentKeyLocation: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyContentEncryptionKeyFromHeader(),
           // This will work..
           contentKeyLocation: {
              odatatype: "#Microsoft.Media.ContentKeyPolicyPlayReadyContentEncryptionKeyFromHeader"
            },
            contentType: 'UltraVioletDownload',
            licenseType: 'NonPersistent'
        }]
    },
    // Same for restriction 
    restriction: {
      odatatype: "#Microsoft.Media.ContentKeyPolicyOpenRestriction"
    }
}]};

return azureMediaServicesClient.contentKeyPolicies.createOrUpdate("<MASKED>", "<MASKED>", "test-policy-1", contentKeyPolicyPlain)
    .then(function (result) {
        console.log("The result is:");
        console.log(result);
    }).catch(function (err) {
        console.error(err);
    });

I agree that this experience is not acceptable and we will provide a better experience in the new TypeScript SDK at the earliest.

@amarzavery
Copy link
Contributor

You can find a reference to the basic uml diagram of contentKeyPolcies over here. Opening the image in a new tab should give a better view.

@aaani
Copy link
Author

aaani commented Jun 8, 2018

Thanks @amarzavery. This parameters object worked for me:

const contentKeyPolicyPlain = {
    options: [{
        configuration: {
            responseCustomData: null,
            licenses: [{
                allowTestDevices: true,
                // This will not help..
                // contentKeyLocation: new AzureMediaServicesModels.ContentKeyPolicyPlayReadyContentEncryptionKeyFromHeader(),
                // This will work..
                contentKeyLocation: {
                    odatatype: "#Microsoft.Media.ContentKeyPolicyPlayReadyContentEncryptionKeyFromHeader"
                },
                contentType: 'UltraVioletDownload',
                licenseType: 'NonPersistent'
            }],
            odatatype: "#Microsoft.Media.ContentKeyPolicyPlayReadyConfiguration"
        },
        // Same for restriction
        restriction: {
            odatatype: "#Microsoft.Media.ContentKeyPolicyOpenRestriction"
        }
    }]
};

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
customer-reported This issue was reported by a customer.
Projects
None yet
Development

No branches or pull requests

4 participants