diff --git a/src/services/contract-services/index.js b/src/services/contract-services/index.js index c3f399d62..a0db2f507 100644 --- a/src/services/contract-services/index.js +++ b/src/services/contract-services/index.js @@ -1,3 +1,5 @@ import { loadContractServicePlan } from './load-contract-service-plan' import { makeContractBaseUrl } from './make-contract-base-url' -export { loadContractServicePlan, makeContractBaseUrl } +import { loadProductsListService } from './load-products-list-service' + +export { loadContractServicePlan, makeContractBaseUrl, loadProductsListService } diff --git a/src/services/contract-services/load-products-list-service.js b/src/services/contract-services/load-products-list-service.js new file mode 100644 index 000000000..ee016cd99 --- /dev/null +++ b/src/services/contract-services/load-products-list-service.js @@ -0,0 +1,21 @@ +import { AxiosHttpClientAdapter, parseHttpResponse } from '../axios/AxiosHttpClientAdapter' +import { makeContractBaseUrl } from './make-contract-base-url' + +export const loadProductsListService = async ({ clientId }) => { + let httpResponse = await AxiosHttpClientAdapter.request({ + url: `${makeContractBaseUrl()}/${clientId}/products`, + method: 'GET' + }) + const parsedData = adapt(httpResponse) + return parseHttpResponse(parsedData) +} + +const adapt = (httpResponse) => { + const products = httpResponse.body || [] + const slugs = products?.map((product) => product.slug) + + return { + body: { slugs }, + statusCode: httpResponse.statusCode + } +} diff --git a/src/services/edge-application-origins-services/create-origin-service.js b/src/services/edge-application-origins-services/create-origin-service.js index c440784bd..a17436518 100644 --- a/src/services/edge-application-origins-services/create-origin-service.js +++ b/src/services/edge-application-origins-services/create-origin-service.js @@ -23,6 +23,14 @@ const adapt = (payload) => { } } + if (payload.originType === 'live_ingest') { + return { + name: payload.name, + origin_type: payload.originType, + streaming_endpoint: payload.streamingEndpoint + } + } + return { name: payload.name, origin_type: payload.originType, diff --git a/src/services/edge-application-origins-services/edit-origin-service.js b/src/services/edge-application-origins-services/edit-origin-service.js index 7a89f7690..6cfa5c2ff 100644 --- a/src/services/edge-application-origins-services/edit-origin-service.js +++ b/src/services/edge-application-origins-services/edit-origin-service.js @@ -23,6 +23,14 @@ const adapt = (payload) => { } } + if (payload.originType === 'live_ingest') { + return { + name: payload.name, + origin_type: payload.originType, + streaming_endpoint: payload.streamingEndpoint + } + } + let payloadAdapted = { name: payload.name, host_header: payload.hostHeader, diff --git a/src/services/edge-application-origins-services/list-origins-service.js b/src/services/edge-application-origins-services/list-origins-service.js index 646c44d41..1e1c394ca 100644 --- a/src/services/edge-application-origins-services/list-origins-service.js +++ b/src/services/edge-application-origins-services/list-origins-service.js @@ -37,10 +37,13 @@ const adapt = (httpResponse) => { originId: convertOriginIdToString(origin.origin_id), name: origin.name, originType: originTypeFormat[origin.origin_type], - addresses: formattedListOfAddresses, + addresses: + origin.origin_type === 'live_ingest' + ? [origin.streaming_endpoint] + : formattedListOfAddresses, originProtocolPolicy: origin.origin_protocol_policy, isOriginRedirectionEnabled: origin.is_origin_redirection_enabled, - hostHeader: origin.host_header, + hostHeader: origin.origin_type === 'live_ingest' ? '-' : origin.host_header, method: origin.method, originPath: origin.origin_path, connectionTimeout: origin.connection_timeout, diff --git a/src/services/edge-application-origins-services/load-origin-service.js b/src/services/edge-application-origins-services/load-origin-service.js index 9deb01603..829a78e56 100644 --- a/src/services/edge-application-origins-services/load-origin-service.js +++ b/src/services/edge-application-origins-services/load-origin-service.js @@ -13,6 +13,19 @@ export const loadOriginService = async ({ edgeApplicationId, id }) => { const adapt = (httpResponse) => { const origin = httpResponse.body?.results + if (origin.origin_type === 'live_ingest') { + return { + body: { + originId: origin.origin_id, + originKey: origin.origin_key, + name: origin.name, + originType: origin.origin_type, + streamingEndpoint: origin.streaming_endpoint + }, + statusCode: httpResponse.statusCode + } + } + const parsedBody = { originId: origin.origin_id, originKey: origin.origin_key, diff --git a/src/tests/services/edge-application-origins-services/create-origin-service.test.js b/src/tests/services/edge-application-origins-services/create-origin-service.test.js index 749e463ce..9f4dbf839 100644 --- a/src/tests/services/edge-application-origins-services/create-origin-service.test.js +++ b/src/tests/services/edge-application-origins-services/create-origin-service.test.js @@ -26,6 +26,11 @@ const fixtures = { connectionTimeout: 60, timeoutBetweenBytes: 35 }, + requestPayloadMockLiveIngest: { + name: 'New Origin', + originType: 'live_ingest', + streamingEndpoint: 'br-east-1.azioningest.net' + }, adaptedPayloadMock: { name: 'New Origin', origin_type: 'single_origin', @@ -107,6 +112,15 @@ const scenarios = [ bucket: 'my-bucket', prefix: '/' } + }, + { + label: 'should call API with correct params when origin type is live ingest', + payload: fixtures.requestPayloadMockLiveIngest, + adaptedPayload: { + name: 'New Origin', + origin_type: 'live_ingest', + streaming_endpoint: 'br-east-1.azioningest.net' + } } ] diff --git a/src/tests/services/edge-application-origins-services/edit-origin-service.test.js b/src/tests/services/edge-application-origins-services/edit-origin-service.test.js index 2a0106909..051823ffc 100644 --- a/src/tests/services/edge-application-origins-services/edit-origin-service.test.js +++ b/src/tests/services/edge-application-origins-services/edit-origin-service.test.js @@ -39,6 +39,13 @@ const fixtures = { bucketName: 'my-bucket', prefix: '/test' }, + requestPayloadMockLiveIngest: { + id: '0000000-00000000-00a0a00s0as0-000000', + edgeApplicationId: 123, + name: 'New Origin', + originType: 'live_ingest', + streamingEndpoint: 'br-east-1.azioningest.net' + }, emptyPrefixOrigin: { id: '0000000-00000000-00a0a00s0as0-000000', edgeApplicationId: 123, @@ -120,6 +127,28 @@ describe('EdgeApplicationOriginsServices', () => { } }) }) + + it('should call API with correct params when origin type is live ingest', async () => { + const requestSpy = vi.spyOn(AxiosHttpClientAdapter, 'request').mockResolvedValueOnce({ + statusCode: 200 + }) + + const { sut } = makeSut() + const version = 'v3' + + await sut(fixtures.requestPayloadMockLiveIngest) + + expect(requestSpy).toHaveBeenCalledWith({ + url: `${version}/edge_applications/${fixtures.requestPayloadMockLiveIngest.edgeApplicationId}/origins/${fixtures.requestPayloadMockLiveIngest.id}`, + method: 'PATCH', + body: { + origin_type: fixtures.requestPayloadMockLiveIngest.originType, + name: fixtures.requestPayloadMockLiveIngest.name, + streaming_endpoint: fixtures.requestPayloadMockLiveIngest.streamingEndpoint + } + }) + }) + it('should adapt prefix to / when the field is empty', async () => { const requestSpy = vi.spyOn(AxiosHttpClientAdapter, 'request').mockResolvedValueOnce({ statusCode: 200 diff --git a/src/tests/services/edge-application-origins-services/list-origins-service.test.js b/src/tests/services/edge-application-origins-services/list-origins-service.test.js index c74f87852..76a17e96b 100644 --- a/src/tests/services/edge-application-origins-services/list-origins-service.test.js +++ b/src/tests/services/edge-application-origins-services/list-origins-service.test.js @@ -28,6 +28,13 @@ const fixtures = { hmac_access_key: '', hmac_secret_key: '' }, + originLiveIngestType: { + origin_id: '111111', + origin_key: '11111-0000-11111-111111-11111', + name: 'Origin 2', + origin_type: 'live_ingest', + streaming_endpoint: 'br-east-1.azioningest.net' + }, originLoadBalancerType: { origin_id: '111111', origin_key: '11111-0000-11111-111111-11111', @@ -84,7 +91,11 @@ describe('EdgeApplicationOriginsServices', () => { vi.spyOn(AxiosHttpClientAdapter, 'request').mockResolvedValueOnce({ statusCode: 200, body: { - results: [fixtures.originSingleType, fixtures.originLoadBalancerType] + results: [ + fixtures.originSingleType, + fixtures.originLoadBalancerType, + fixtures.originLiveIngestType + ] } }) @@ -92,7 +103,7 @@ describe('EdgeApplicationOriginsServices', () => { const { sut } = makeSut() const result = await sut({ id: edgeApplicationId }) - const [singleType, loadBalancerType] = result + const [singleType, loadBalancerType, liveIngestType] = result expect(singleType).toEqual({ id: fixtures.originSingleType.origin_key, @@ -137,5 +148,22 @@ describe('EdgeApplicationOriginsServices', () => { hmacAccessKey: fixtures.originLoadBalancerType.hmac_access_key, hmacSecretKey: fixtures.originLoadBalancerType.hmac_secret_key }) + + expect(liveIngestType).toEqual({ + id: fixtures.originLiveIngestType.origin_key, + originKey: { + content: fixtures.originLiveIngestType.origin_key + }, + connectionTimeout: undefined, + hmacAccessKey: undefined, + hmacAuthentication: undefined, + hmacRegionName: undefined, + hmacSecretKey: undefined, + hostHeader: '-', + originId: fixtures.originLiveIngestType.origin_id, + name: fixtures.originLiveIngestType.name, + originType: 'Live Ingest', + addresses: ['br-east-1.azioningest.net'] + }) }) }) diff --git a/src/views/EdgeApplicationsOrigins/Drawer/index.vue b/src/views/EdgeApplicationsOrigins/Drawer/index.vue index 78002c897..8178a8ed9 100644 --- a/src/views/EdgeApplicationsOrigins/Drawer/index.vue +++ b/src/views/EdgeApplicationsOrigins/Drawer/index.vue @@ -5,6 +5,9 @@ import CopyKeyDialog from '@templates/dialog-copy-key' import { refDebounced } from '@vueuse/core' import { useToast } from 'primevue/usetoast' + import { onMounted } from 'vue' + import { useAccountStore } from '@/stores/account' + import { loadProductsListService } from '@/services/contract-services' import { useDialog } from 'primevue/usedialog' import { createOriginService } from '@/services/edge-application-origins-services' import { inject, ref } from 'vue' @@ -47,14 +50,28 @@ } }) + onMounted(async () => { + const products = await loadProductsListService({ clientId: accountStore.account.client_id }) + if (products.slugs.includes('live_ingest')) { + hasLiveIngest.value = true + } + originTypesOptions.value.push({ + label: 'Live Ingest', + value: 'live_ingest', + disabled: !hasLiveIngest.value + }) + }) + + const accountStore = useAccountStore() const toast = useToast() const showCreateOriginDrawer = ref(false) + const hasLiveIngest = ref(false) const showEditOriginDrawer = ref(false) const debouncedDrawerAnimate = 300 const loadCreateOriginDrawer = refDebounced(showCreateOriginDrawer, debouncedDrawerAnimate) const loadEditOriginDrawer = refDebounced(showEditOriginDrawer, debouncedDrawerAnimate) const selectedOriginToEdit = ref('') - const ORIGIN_TYPES_OPTIONS = [ + const originTypesOptions = ref([ { label: 'Single Origin', value: 'single_origin', @@ -70,7 +87,7 @@ value: 'object_storage', disabled: false } - ] + ]) const initialValues = ref({ id: props.edgeApplicationId, @@ -109,11 +126,11 @@ .string() .label('Host Header') .when('originType', { - is: (originType) => originType !== 'object_storage', + is: (originType) => originType !== 'object_storage' && originType !== 'live_ingest', then: (schema) => schema.required() }), addresses: yup.array().when('originType', { - is: (originType) => originType === 'object_storage', + is: (originType) => originType === 'object_storage' || originType === 'live_ingest', then: (schema) => schema.optional(), otherwise: (schema) => schema.of( @@ -130,6 +147,13 @@ return /^(\/\.?[\w][\w.-]*)+$/.test(value) || !value }) .label('Origin Path'), + streamingEndpoint: yup + .string() + .label('Streaming Endpoint') + .when('originType', { + is: (originType) => originType === 'live_ingest', + then: (schema) => schema.required() + }), hmacAuthentication: yup.boolean(), hmacRegionName: yup .string() @@ -203,10 +227,6 @@ emit('onSuccess') } - const closeDrawerEdit = () => { - showEditOriginDrawer.value = false - } - const handleTrackCreation = () => { tracker.product .productCreated({ @@ -235,8 +255,6 @@ errorType: 'api' }) .track() - - closeDrawerEdit() } const handleFailedCreateOrigin = (error) => { @@ -289,7 +307,7 @@ @@ -310,7 +328,7 @@ diff --git a/src/views/EdgeApplicationsOrigins/FormFields/FormFieldsEdgeApplicationsOrigins.vue b/src/views/EdgeApplicationsOrigins/FormFields/FormFieldsEdgeApplicationsOrigins.vue index cac155ad7..5aec3ab3b 100644 --- a/src/views/EdgeApplicationsOrigins/FormFields/FormFieldsEdgeApplicationsOrigins.vue +++ b/src/views/EdgeApplicationsOrigins/FormFields/FormFieldsEdgeApplicationsOrigins.vue @@ -58,6 +58,14 @@ { title: 'Backup', inputValue: 'backup' } ] + const STREAMING_ENDPOINT_OPTIONS = [ + 'br-east-1.azioningest.net', + 'br-east-2.azioningest.net', + 'br-east-3.azioningest.net', + 'us-east-1.azioningest.net', + 'us-east-2.azioningest.net' + ] + const originKeyInput = ref(null) const { value: originKey, setValue: setOriginKey } = useField('originKey') @@ -72,6 +80,7 @@ const { value: originType } = useField('originType') useField('originProtocolPolicy') const { value: method } = useField('method') + const { value: streamingEndpoint } = useField('streamingEndpoint') const { value: originPath } = useField('originPath') const { value: connectionTimeout } = useField('connectionTimeout') const { value: timeoutBetweenBytes } = useField('timeoutBetweenBytes') @@ -83,6 +92,7 @@ const { value: prefix } = useField('prefix') const isSingleOriginType = computed(() => originType.value === 'single_origin') + const isLiveIngestOriginType = computed(() => originType.value === 'live_ingest') const isLoadBalancerOriginType = computed(() => originType.value === 'load_balancer') const isObjectStorageOriginType = computed(() => originType.value === 'object_storage') const isHmacAuthentication = computed(() => !!hmacAuthentication.value) @@ -105,6 +115,10 @@ method.value = 'ip_hash' pushAddress({ ...defaultAddress }) } + if (!connectionTimeout.value || !timeoutBetweenBytes.value) { + connectionTimeout.value = 60 + timeoutBetweenBytes.value = 120 + } } const removeCurrentAddress = (index) => { @@ -216,7 +230,22 @@ :description="descriptionOriginType" /> -
+
+ +
+