Skip to content

Commit

Permalink
fix(FEC-8660): handle API block action (#67)
Browse files Browse the repository at this point in the history
Identify and handle block action in API response.
Added block action handling, and use event to signal to application when block action occur.
Also added new category and codes for block action and invalid request data.
  • Loading branch information
OrenMe authored Nov 18, 2018
1 parent 695f68a commit 78b3f22
Show file tree
Hide file tree
Showing 16 changed files with 84 additions and 73 deletions.
4 changes: 2 additions & 2 deletions dist/playkit-analytics-service.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/playkit-analytics-service.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/playkit-bookmark-service.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/playkit-bookmark-service.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/playkit-ott-provider.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/playkit-ott-provider.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/playkit-ovp-provider.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/playkit-ovp-provider.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/playkit-stats-service.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/playkit-stats-service.js.map

Large diffs are not rendered by default.

28 changes: 12 additions & 16 deletions src/k-provider/common/base-provider-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import MediaSources from '../../entities/media-sources';
import MediaSource from '../../entities/media-source';
import type {OTTKalturaPlaybackSource} from '../ott/response-types/kaltura-playback-source';
import type {OVPKalturaPlaybackSource} from '../ovp/response-types/kaltura-playback-source';
import KalturaRuleAction from './response-types/kaltura-rule-action';
import KalturaAccessControlMessage from './response-types/kaltura-access-control-message';

export default class BaseProviderParser {
// eslint-disable-next-line no-unused-vars
Expand All @@ -27,25 +29,19 @@ export default class BaseProviderParser {
return !!sourceFormat && sourceFormat.name === 'mp4';
}

static hasBlockActions(assetResponse: any): any {
static hasBlockAction(assetResponse: any): boolean {
return BaseProviderParser.getBlockAction(assetResponse) !== undefined;
}

static getBlockAction(assetResponse: any): ?KalturaRuleAction {
let blockAction;
if (assetResponse && assetResponse.playBackContextResult) {
const playbackContext = assetResponse.playBackContextResult;
for (let actionIndex = 0; actionIndex < playbackContext.actions.length; actionIndex++) {
if (playbackContext.actions[actionIndex].type === 'BLOCK') {
return playbackContext.actions[actionIndex];
}
}
blockAction = assetResponse.playBackContextResult.actions.find(action => action.type === KalturaRuleAction.Type.BLOCK);
}
return null;
return blockAction;
}

static hasErrorMessage(assetResponse: any): any {
const messages = assetResponse.playBackContextResult.messages;
for (let messagesIndex = 0; messagesIndex < messages.length; messagesIndex++) {
if (messages[messagesIndex].code !== 'OK') {
return messages[messagesIndex];
}
}
return null;
static getErrorMessages(assetResponse: any): Array<KalturaAccessControlMessage> {
return assetResponse.playBackContextResult.messages;
}
}
16 changes: 11 additions & 5 deletions src/k-provider/common/multi-request-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,18 @@ export default class MultiRequestBuilder extends RequestBuilder {
* @returns {Promise} The multirequest execution promise
*/
execute(): Promise<Object> {
try {
this.params = JSON.stringify(this.params);
} catch (err) {
MultiRequestBuilder._logger.error(`${err.message}`);
}
return new Promise((resolve, reject) => {
try {
this.params = JSON.stringify(this.params);
} catch (err) {
MultiRequestBuilder._logger.error(`${err.message}`);
reject(
new Error(Error.Severity.CRITICAL, Error.Category.PROVIDER, Error.Code.FAILED_PARSING_REQUEST, {
error: err,
params: this.params
})
);
}
this.doHttpRequest().then(
data => {
const multiRequestResult = new MultiRequestResult(data);
Expand Down
25 changes: 11 additions & 14 deletions src/k-provider/ott/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import OTTProviderParser from './provider-parser';
import KalturaAsset from './response-types/kaltura-asset';
import KalturaPlaybackContext from './response-types/kaltura-playback-context';
import MediaEntry from '../../entities/media-entry';
import Error from '../../util/error/error';

export default class OTTProvider extends BaseProvider<OTTProviderMediaInfoObject> {
_networkRetryConfig: ProviderNetworkRetryParameters;
Expand Down Expand Up @@ -62,20 +63,20 @@ export default class OTTProvider extends BaseProvider<OTTProviderMediaInfoObject
mediaType: mediaType,
formats: mediaInfo.formats || []
};
this._dataLoader.fetchData().then(
return this._dataLoader.fetchData().then(
response => {
try {
resolve(this._parseDataFromResponse(response, requestData));
} catch (err) {
reject({success: false, data: err});
reject(err);
}
},
err => {
reject(err);
}
);
} else {
reject({success: false, data: 'Missing mandatory parameter'});
reject(new Error(Error.Severity.CRITICAL, Error.Category.PROVIDER, Error.Code.MISSING_MANDATORY_PARAMS, {message: 'missing entry id'}));
}
});
}
Expand Down Expand Up @@ -120,18 +121,14 @@ export default class OTTProvider extends BaseProvider<OTTProviderMediaInfoObject
if (data.has(OTTAssetLoader.id)) {
const assetLoader = data.get(OTTAssetLoader.id);
if (assetLoader && assetLoader.response && Object.keys(assetLoader.response).length) {
const blockedAction = OTTProviderParser.hasBlockActions(assetLoader.response);
if (blockedAction) {
const errorMessage = OTTProviderParser.hasErrorMessage(assetLoader.response);
if (errorMessage) {
this._logger.error(`Asset is blocked, error message: `, errorMessage);
throw errorMessage;
} else {
this._logger.error(`Asset is blocked, action: `, blockedAction);
throw blockedAction;
}
const response = assetLoader.response;
if (OTTProviderParser.hasBlockAction(response)) {
throw new Error(Error.Severity.CRITICAL, Error.Category.SERVICE, Error.Code.BLOCK_ACTION, {
action: OTTProviderParser.getBlockAction(response),
messages: OTTProviderParser.getErrorMessages(response)
});
}
const mediaEntry = OTTProviderParser.getMediaEntry(assetLoader.response, requestData);
const mediaEntry = OTTProviderParser.getMediaEntry(response, requestData);
const mediaSources = mediaEntry.sources.toJSON();
mediaConfig.sources.hls = mediaSources.hls;
mediaConfig.sources.dash = mediaSources.dash;
Expand Down
37 changes: 16 additions & 21 deletions src/k-provider/ovp/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import OVPPlaylistLoader from './loaders/playlist-loader';
import BaseProvider from '../common/base-provider';
import MediaEntry from '../../entities/media-entry';
import OVPEntryListLoader from './loaders/entry-list-loader';
import Error from '../../util/error/error';

export default class OVPProvider extends BaseProvider<ProviderMediaInfoObject> {
_filterOptionsConfig: ProviderFilterOptionsObject = {redirectFromEntryId: true};
Expand Down Expand Up @@ -46,16 +47,20 @@ export default class OVPProvider extends BaseProvider<ProviderMediaInfoObject> {
}
const redirectFromEntryId = this._getEntryRedirectFilter(mediaInfo);
this._dataLoader.add(OVPMediaEntryLoader, {entryId, ks, redirectFromEntryId});
this._dataLoader.fetchData().then(
return this._dataLoader.fetchData().then(
response => {
resolve(this._parseDataFromResponse(response));
try {
resolve(this._parseDataFromResponse(response));
} catch (err) {
reject(err);
}
},
err => {
reject(err);
}
);
} else {
reject({success: false, data: 'Missing mandatory parameter'});
reject(new Error(Error.Severity.CRITICAL, Error.Category.PROVIDER, Error.Code.MISSING_MANDATORY_PARAMS, {message: 'missing entry id'}));
}
});
}
Expand Down Expand Up @@ -101,8 +106,14 @@ export default class OVPProvider extends BaseProvider<ProviderMediaInfoObject> {
if (data.has(OVPMediaEntryLoader.id)) {
const mediaLoader = data.get(OVPMediaEntryLoader.id);
if (mediaLoader && mediaLoader.response) {
this._validateData(mediaLoader.response);
const mediaEntry = OVPProviderParser.getMediaEntry(this.isAnonymous ? '' : this.ks, this.partnerId, this.uiConfId, mediaLoader.response);
const response = mediaLoader.response;
if (OVPProviderParser.hasBlockAction(response)) {
throw new Error(Error.Severity.CRITICAL, Error.Category.SERVICE, Error.Code.BLOCK_ACTION, {
action: OVPProviderParser.getBlockAction(response),
messages: OVPProviderParser.getErrorMessages(response)
});
}
const mediaEntry = OVPProviderParser.getMediaEntry(this.isAnonymous ? '' : this.ks, this.partnerId, this.uiConfId, response);
Object.assign(mediaConfig.sources, this._getSourcesObject(mediaEntry));
}
}
Expand Down Expand Up @@ -151,7 +162,6 @@ export default class OVPProvider extends BaseProvider<ProviderMediaInfoObject> {
if (data && data.has(OVPPlaylistLoader.id)) {
const playlistLoader = data.get(OVPPlaylistLoader.id);
if (playlistLoader && playlistLoader.response) {
this._validateData(playlistLoader.response);
const playlist = OVPProviderParser.getPlaylist(playlistLoader.response);
playlistConfig.id = playlist.id;
playlistConfig.poster = playlist.poster;
Expand Down Expand Up @@ -204,7 +214,6 @@ export default class OVPProvider extends BaseProvider<ProviderMediaInfoObject> {
if (data && data.has(OVPPlaylistLoader.id)) {
const playlistLoader = data.get(OVPPlaylistLoader.id);
if (playlistLoader && playlistLoader.response) {
this._validateData(playlistLoader.response);
const entryList = OVPProviderParser.getEntryList(playlistLoader.response);
entryList.items.forEach(i => playlistConfig.items.push({sources: this._getSourcesObject(i)}));
}
Expand All @@ -225,20 +234,6 @@ export default class OVPProvider extends BaseProvider<ProviderMediaInfoObject> {
};
}

_validateData(response: any): void {
const blockedAction = OVPProviderParser.hasBlockActions(response);
if (blockedAction) {
const errorMessage = OVPProviderParser.hasErrorMessage(response);
if (errorMessage) {
this._logger.error(`Entry is blocked, error message: `, errorMessage);
throw errorMessage;
} else {
this._logger.error(`Entry is blocked, action: `, blockedAction);
throw blockedAction;
}
}
}

_getDefaultSourcesObject(): ProviderMediaConfigSourcesObject {
return {
hls: [],
Expand Down
4 changes: 3 additions & 1 deletion src/util/error/category.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ type CategoryType = {[category: string]: number};

const Category: CategoryType = {
/** Errors from the network stack. */
NETWORK: 1
NETWORK: 1,
SERVICE: 2,
PROVIDER: 3
};

export {Category};
Expand Down
17 changes: 16 additions & 1 deletion src/util/error/code.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,22 @@ const Code: CodeType = {
/**
* The server response had a valid structure and valid API result, but it did not match the request
*/
API_RESPONSE_MISMATCH: 1007
API_RESPONSE_MISMATCH: 1007,

/**
* The server responded with an error
*/
ERROR: 2000,

/**
* The server responded with a block action
*/
BLOCK_ACTION: 2001,

/**
* The server responded with a block action
*/
MISSING_MANDATORY_PARAMS: 3000
};

export {Code};
Expand Down

0 comments on commit 78b3f22

Please sign in to comment.