Debugging remote delivery profile created through api

I can successfully create remote s3 storage and delivery manually through the web UI, but I would like to automatically register partners and setup remote storage and delivery through the api.

I tried using create_remote_storage.php, and the storage export to S3 works, but when I go to play the entry the video player fails to find the media.

I even tried setting up a template partner with correct remote storage and delivery working manually, but the new partner based on the template doesn’t deliver the video.

How can I fix and/or debug this setup?

I also keep getting errors like:

log/kaltura_api_v3.log:952938:2017-07-15 07:24:16 [0.001412] [172.17.0.1] [92926190] [69] [API] [DeliveryProfilePeer::getRemoteDeliveryByStorageId] ERR: exception ‘Exception’ with message ‘Delivery ID can’t be determined for storageId [6] ( PartnerId [103] ) and streamer type [ rtmp ]’ in /opt/kaltura/app/infra/log/KalturaLog.php:83
log/kaltura_prod.log:507:2017-07-15 07:07:22 [0.000643] [172.17.0.1] [1249629682] [30] [PS2] [DeliveryProfilePeer::getRemoteDeliveryByStorageId] ERR: exception ‘Exception’ with message ‘Delivery ID can’t be determined for storageId [6] ( PartnerId [103] ) and streamer type [ applehttp ]’ in /opt/kaltura/app/infra/log/KalturaLog.php:83

Why is it trying to find a delivery profile for the wrong streamer type? The remote storage profile and the delivery profile are both set to HTTP.

It also seems that the player is requesting the media with a url that looks like:
http://dockerhost/p/104/sp/10400/playManifest/entryId/0_gjvmfhfi/flavorIds/0_dcbr9lk7/format/applehttp/protocol/http/a.m3u8

This causes the log message to appear. But when I alter the url to look like:

http://dockerhost/p/104/sp/10400/playManifest/entryId/0_gjvmfhfi/flavorIds/0_dcbr9lk7/format/http/protocol/http/a.mp4

The manifest appears to return the correct remote url for the player. How can I get the player to request the second url using the “http” streamer type?

Hi @cbwilkes,

A general explanation on how delivery profiles are configured by default can be found in these threads:


If I understand your current situation correctly, the remote storage profile is correctly configured and you are able to export to S3 but the delivery profile is giving you issues.

After going through my explanations in these two threads, if you still need assistance, kindly post the output for:

mysql> select id, partner_id,name,url,host_name, type, streamer_type, is_default from delivery_profile;

And let’s see where we stand.
I would not recommend delivering the video without use of an adaptive bitrate protocol [HLS, HDS or DASH]. By default, CE uses the Kaltura Nginx VOD module to repack the MP4 assets so that serving is done using HLS so, the playManifest request goes from the player to the server, requesting an ‘applehttp’ manifest [i.e: HLS], the returned m3u8 will include different URIs, one for each ‘flavour’ of the entry in question. Based on network conditions and device, the most suitable video fragments shall be served.

Thanks jess, I’ll look through the documents.

I was able to get the players to stream the video by setting the flashvars[disableHLSOnJs]=true.

With disableHLSOnJs set the player would request a link like this:
http://dockerhost/p/101/sp/10100/playManifest/entryId/0_a41bojhz/flavorId/0_zlx2qizc/format/url/protocol/http/a.mp4?referrer=ZmlsZTovLy9ob21l&playSessionId=630e3ba6-77bc-7d78-4f2f-3753075bf7a0&clientTag=html5:v2.57&uiConfId=23448125

This url would at least redirect to my cloudfront end point:

$ curl -v “http://dockerhost/p/101/sp/10100/playManifest/entryId/0_a41bojhz/flavorId/0_zlx2qizc/format/url/protocol/http/a.mp4?referrer=ZmlsZTovLy9ob21l&playSessionId=630e3ba6-77bc-7d78-4f2f-3753075bf7a0&clientTag=html5:v2.57&uiConfId=23448125

  • Trying 127.0.0.1…
  • Connected to dockerhost (127.0.0.1) port 80 (#0)

GET /p/101/sp/10100/playManifest/entryId/0_a41bojhz/flavorId/0_zlx2qizc/format/url/protocol/http/a.mp4?referrer=ZmlsZTovLy9ob21l&playSessionId=630e3ba6-77bc-7d78-4f2f-3753075bf7a0&clientTag=html5:v2.57&uiConfId=23448125 HTTP/1.1
Host: dockerhost
User-Agent: curl/7.47.0
Accept: /

< HTTP/1.1 302 Found
< Date: Mon, 17 Jul 2017 11:29:09 GMT
< Server: Apache/2.2.15 (CentOS)
< X-Powered-By: PHP/5.3.3
< X-Kaltura-Session: 1654061308
< Expires: Mon, 17 Jul 2017 11:30:09 GMT
< Cache-Control: private, max-age=60, max-stale=0
< Pragma: no-cache
< location: https://dxxxxxxxxxxxx.cloudfront.net/kaltura/content/entry/data/0/0/0_a41bojhz_0_zlx2qizc_2.mp4
< Access-Control-Allow-Origin: *
< Access-Control-Expose-Headers: Server,range,Content-Length,Content-Range
< Last-modified: Mon, 17 Jul 2017 11:29:09 GMT
< Content-Length: 1
< X-Me: dockerhost
< Connection: close
< Content-Type: text/html; charset=UTF-8
<

Without the disableHLSOnJs I get the kaltlog error:

2017-07-17 14:11:10 [0.000746] [172.17.0.1] [1308043122] [30] [PS2] 
[DeliveryProfilePeer::getRemoteDeliveryByStorageId] ERR: exception 'Exception' with message 'Delivery ID can't be determined for storageId [2] ( PartnerId [101] ) and streamer type [ applehttp ]' in /opt/kaltura/app/infra/log/KalturaLog.php:83

And the player looks for:
http://dockerhost/p/101/sp/10100/playManifest/entryId/0_a41bojhz/flavorIds/0_otovu6ly/format/applehttp/protocol/http/a.m3u8?referrer=ZmlsZTovLy9ob21l&playSessionId=32193a02-3cc2-25fb-c7df-de0f74866045&clientTag=html5:v2.57&uiConfId=23448125&responseFormat=jsonp&callback=jQuery11110500286841444615_1500291258207&_=1500291258208

Mysql Output:

mysql> select id, partner_id,name,url,host_name, type, streamer_type, is_default from delivery_profile;
+------+------------+------------------------------------------------+----------------------------------------------+------------------------------+------+-------------------+------------+
| id   | partner_id | name                                           | url                                          | host_name                    | type | streamer_type     | is_default |
+------+------------+------------------------------------------------+----------------------------------------------+------------------------------+------+-------------------+------------+
|    1 |          0 | Default HTTP Delivery Profile                  | http://dockerhost:80                         | dockerhost                   |   10 | applehttp         |          0 |
|    2 |          0 | Default HTTP Delivery Profile                  | http://dockerhost:80                         | dockerhost                   |   14 | http              |          1 |
|    3 |          0 | Default HLS Live Delivery Profile              | NULL                                         | NULL                         | 1001 | applehttp         |          1 |
|    4 |          0 | Default HLS Network Live Delivery Profile      | NULL                                         | NULL                         | 1001 | hls               |          1 |
|    5 |          0 | Default HLS To Multicast Live Delivery Profile | NULL                                         | NULL                         | 1006 | applehttp_to_mc   |          1 |
|  301 |          0 | Default MPEG-DASH Live Delivery Profile        | NULL                                         | NULL                         | 1003 | mpegdash          |          1 |
|  302 |          0 | Default HD Network Live Delivery Profile       | NULL                                         | NULL                         | 1002 | hdnetworkmanifest |          1 |
|  303 |          0 | Default HDS Live Delivery Profile              | NULL                                         | NULL                         | 1002 | hds               |          1 |
|  304 |          0 | Default RTMP Live Delivery Profile             | NULL                                         | NULL                         | 1005 | rtmp              |          1 |
| 1001 |          0 | Kaltura HLS segmentation                       | http://127.0.0.1:88/hls                      | 127.0.0.1                    |   61 | applehttp         |          1 |
| 1002 |          0 | Kaltura HDS segmentation                       | http://127.0.0.1:88/hds                      | 127.0.0.1                    |   63 | hdnetworkmanifest |          1 |
| 1003 |          0 | Kaltura DASH segmentation                      | http://127.0.0.1:88/dash                     | 127.0.0.1                    |   68 | mpegdash          |          1 |
| 1004 |        101 | AWS S3 1                                       | https://dxxxxxxxxxxxx.cloudfront.net/kaltura | dxxxxxxxxxxxx.cloudfront.net |    4 | http              |          0 |
+------+------------+------------------------------------------------+----------------------------------------------+------------------------------+------+-------------------+------------+
13 rows in set (0.00 sec)

Few Questions:

  1. It’s possible to repackage cloudfront or another HTTP-based CDN urls into HLS without going through nginx?
  2. Why do the players continue to attempt the to look for an applehttp delivery streamerType? Is there a cleaner way to convince to players to use my delivery profile (which is currently set to http)?

Thanks,
Curtis

Hi @cbwilkes,

RE #1 - see my answer here: Abcdomain.com:88/hls
RE #2 - like I said, the default playback method the player will use is HLS. If you wish for progressive download to be used permanently, you can go to KMC->Studio->Your player->Plugins->UI Variables and set:
disableHLSOnJs=true

But as I also explained, I don’t really recommend serving content without use of one of the adaptive bitrate protocols.

Thanks, @jess I can at least get the video playing through cloudfront. I’ll have to figure out another setup for the HLS protocol to work.

Thanks,
Curtis

Hi @cbwilkes,

Note that the VOD Nginx module supports three different operation modes. By default, it is configured to use ‘mapped’ mode.
You can see the configuration documentation for it here:

If you wish to, you should be able to configure things so that the delivery profile used will fetch the files from your CF and the VOD module shall serve the manifest.
From your delivery_profile output, I see you made an attempt to configure a CF profile, only you set the streamer type to ‘http’ and not ‘applehttp’ [HLS] and also, is_default is set to 0 and should be set to one if you want it to be the default profile used. When no additional profiles are configured, the one used by default is ID 1001, you can deduce the needed configuration from looking at it and also the posts I referred you to.

Thanks @jess

Also how do I access the storageProfile API? I keep getting forbidden even when I used a -2 admin session.

Hi @cbwilkes,

From the API, you need to use a -2 KS when starting the session but then call:

$client->setPartnerId($partnerId);

And set it to the partner ID the profile should be attached to.
You can see an example here:

However, while it is recommended that you ALWAYS use the API rather than attempt to change DB records directly [for many reasons: relations between tables, sync to Sphinx, etc], in this very particular case, you can also make direct updates to the table’s records, which can sometimes be easier:)

Awesome @jess! You’ve been a great help.

I think I have all the pieces I need to automatically setup remote storage and delivery.

One last question:
Is there a way to require a ks to use the partner.register action? The method seems to be more open than I would like.

Hi @cbwilkes,

First, you’re welcome.
As for your question, luckily, the service permissions mechanism is very modular so that can be changed with relative ease.
There are three DB tables involved:

  • permission
  • permission_item
  • permission_to_permission_item

To properly illustrate the relations, I’ll walk you through the queries and actual results on my own ENV, then you can apply them to yours.

BEFORE YOU START MANIPULATING THESE TABLES, PLEASE BACKUP ALL 3 TABLES.

We start by locating the relevant ID in the permission_item table:

mysql> select * from permission_item where param_1='partner' and param_2='register'\G
*************************** 1. row ***************************
         id: 993
       type: kApiActionPermissionItem
 partner_id: 0
    param_1: partner
    param_2: register
    param_3: 
    param_4: 
    param_5: 
       tags: 
 created_at: 2017-06-29 12:17:13
 updated_at: 2017-06-29 12:17:13
custom_data: NULL

So, in my case, the ID is 993.
Now, let’s check what permissions are associated with this permission_item_id in the permission_to_permission_item table:

mysql> select * from permission_to_permission_item where permission_item_id =993
    -> ;
+------+---------------+--------------------+---------------------+---------------------+
| id   | permission_id | permission_item_id | created_at          | updated_at          |
+------+---------------+--------------------+---------------------+---------------------+
| 2499 |            61 |                993 | 2017-07-18 14:31:57 | 2017-07-18 14:31:57 |
| 2500 |            72 |                993 | 2017-07-18 14:31:57 | 2017-07-18 14:31:57 |
| 2501 |            80 |                993 | 2017-07-18 14:31:57 | 2017-07-18 14:31:57 |
| 2502 |           181 |                993 | 2017-07-18 14:31:57 | 2017-07-18 14:31:57 |
+------+---------------+--------------------+---------------------+---------------------+

So, you can see we have four of these. Let’s see what they are:


mysql> select id,name,friendly_name, description from permission where id in (61,72,80,181);
+-----+------------------------------+----------------------------+----------------------------+
| id  | name                         | friendly_name              | description                |
+-----+------------------------------+----------------------------+----------------------------+
|  61 | ADMIN_PUBLISHER_MANAGE       | Manage publishers          |                            |
|  72 | ALWAYS_ALLOWED_ACTIONS       | No session permission      |                            |
|  80 | BASE_USER_SESSION_PERMISSION | User session permission    |                            |
| 181 | WIDGET_SESSION_PERMISSION    | Anonymous user permissions | Anonymous user permissions |
+-----+------------------------------+----------------------------+----------------------------+

The one you are interested in getting rid of is ID 72.
Now, you didn’t specify what permissions you would like to enforce but I’ll take an educated guess and assume you’d like the registration of a partner to only be allowed when using a -2 KS [-2 is the Admin Console partner ID].
For that, you will need to:

  • Get rid of the ALWAYS_ALLOWED_ACTIONS record:
mysql> delete from permission_to_permission_item where permission_item_id =993 and permission_id=72;

  • Locate the ID for PARTNER_-2_GROUP_*_PERMISSION in permission table (in my case it is 218):
mysql> select * from permission where name = 'PARTNER_-2_GROUP_*_PERMISSION'\G
*************************** 1. row ***************************
                         id: 218
                       type: 4
                       name: PARTNER_-2_GROUP_*_PERMISSION
              friendly_name: Partner -2 permission for group *
                description: Partner -2 permission for group *
                 partner_id: -2
                     status: 1
depends_on_permission_names: 
                       tags: 
                 created_at: 2017-06-29 12:16:48
                 updated_at: 2017-07-03 12:52:17
                custom_data: a:1:{s:13:"partner_group";s:1:"*";}

  • Insert a corresponding record into permission_to_permission_item:
mysql> insert into permission_to_permission_item values (NULL, 218, 993, NOW(), NOW());

After running these queries, when calling the partner->register() action with anything other than a -2 KS, you should get:

        code    SERVICE_FORBIDDEN
        message The access to service [partner->register] is forbidden
        objectType      KalturaAPIException

FYI, the defaults are set in this INI:
/opt/kaltura/app/deployment/permissions/service.partner.ini
So, if you ever deploy a DB from scratch, you can just edit this file BEFORE running the configure scripts so you won’t have to make manual adjustments after the deployment is done.
There is one INI file per service.

Thanks. I was able to do database changes post deployment.

This is what I used for those who may be interested:

$ PERM_ITEM_ID=`mysql -N -u$DB1_USER -p$DB1_PASS -h$DB1_HOST -P$DB1_PORT -e "use $DB1_NAME; select id from permission_item where param_1='partner' and param_2='register';"`
$ PERM_2_ID=`mysql -N -u$DB1_USER -p$DB1_PASS -h$DB1_HOST -P$DB1_PORT -e "use $DB1_NAME; select id from permission where name = 'PARTNER_-2_GROUP_*_PERMISSION';"`
$ PERM_ALWAYS_ID=`mysql -N -u$DB1_USER -p$DB1_PASS -h$DB1_HOST -P$DB1_PORT -e "use $DB1_NAME; select permission_to_permission_item.permission_id from permission_item join permission_to_permission_item ON permission_item.id = permission_to_permission_item.permission_item_id join permission ON permission_to_permission_item.permission_id =  permission.id where permission_item.param_1='partner' and permission_item.param_2='register' and  permission.name = 'ALWAYS_ALLOWED_ACTIONS';"`

$ mysql -u$DB1_USER -p$DB1_PASS -h$DB1_HOST -P$DB1_PORT -e "use $DB1_NAME; delete from permission_to_permission_item where permission_item_id =$PERM_ITEM_ID and permission_id=$PERM_ALWAYS_ID;"
$ mysql -u$DB1_USER -p$DB1_PASS -h$DB1_HOST -P$DB1_PORT -e "use $DB1_NAME; insert into permission_to_permission_item values (NULL, $PERM_2_ID, $PERM_ITEM_ID, NOW(), NOW());"