Skip to content

Commit

Permalink
add template creation to assests creation flow
Browse files Browse the repository at this point in the history
Signed-off-by: Eric <[email protected]>
  • Loading branch information
mengweieric committed Oct 11, 2024
1 parent 9f48704 commit 45f437f
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ interface CollectAndShipDataProps {
selectedDataSourceLabel: string;
}

interface CollectorOption {
export interface CollectorOption {
label: string;
value: string;
}
Expand Down Expand Up @@ -280,7 +280,15 @@ export const CollectAndShipData: React.FC<CollectAndShipDataProps> = ({
</EuiListGroup>
<EuiButton
onClick={async () => {
await UploadAssets(specificMethod, selectedDataSourceId, selectedDataSourceLabel);
await UploadAssets(
specificMethod,
selectedDataSourceId,
selectedDataSourceLabel,
technologyJsonMap[specificMethod]?.['getting-started']?.schema ||
technologyJsonMap[specificMethod]?.schema ||
[],
collectorOptions
);
}}
fill
>
Expand Down
60 changes: 59 additions & 1 deletion public/components/getting_started/components/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,27 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { MappingTypeMapping } from '@opensearch-project/opensearch/api/types';
import { EuiSelectableOption } from '@elastic/eui';
import { coreRefs } from '../../../framework/core_refs';
import { useToast } from '../../../../public/components/common/toast';
import { CollectorOption } from './getting_started_collectData';

export interface ICollectorIndexTemplate {
name: string;
templatePath: string;
template: MappingTypeMapping;
}

export interface ICollectorSchema {
alias: string;
content: string;
description: string;
'index-pattern-name': string;
type: string;
'index-template': string;
info: string[];
}

const fetchAssets = async (tutorialId: string, assetFilter?: 'dashboards' | 'indexPatterns') => {
const assetFilterParam = assetFilter ? `${assetFilter}/` : '';
Expand All @@ -20,16 +39,55 @@ const fetchAssets = async (tutorialId: string, assetFilter?: 'dashboards' | 'ind
return responeData;
};

export const UploadAssets = async (tutorialId: string, mdsId: string, mdsLabel: string) => {
export const UploadAssets = async (
tutorialId: string,
mdsId: string,
mdsLabel: string,
schema: ICollectorSchema[],
collectorOptions: Array<EuiSelectableOption<CollectorOption>>
) => {
const { setToast } = useToast();
const http = coreRefs.http;

let selectedIntegration: string | undefined;
const checkedCollector = collectorOptions.find((collector) => {
return !!collector.checked;
});

if (checkedCollector !== undefined) {
if (checkedCollector.value === 'otel') {
selectedIntegration = 'otel-services';
} else if (checkedCollector.value === 'nginx') {
selectedIntegration = checkedCollector.value;
}
}

try {
// Auto-generate index templates based on the selected integration
let templates: ICollectorIndexTemplate[] = [];
if (selectedIntegration !== undefined) {
const indexTemplateMappings = await http!.get(
`/api/integrations/repository/${selectedIntegration}/schema`
);
templates = schema.reduce((acc: ICollectorIndexTemplate[], sh) => {
const templateMapping = indexTemplateMappings?.data?.mappings?.[sh.type];
if (!!templateMapping) {
acc.push({
name: sh.content.match(/[^/]+$/)?.[0] || '',
templatePath: sh.content.match(/PUT\s+(.+)/)?.[1] || '',
template: templateMapping,
});
}
return acc;
}, []);
}

const response = await http!.post(`/api/observability/gettingStarted/createAssets`, {
body: JSON.stringify({
mdsId,
mdsLabel,
tutorialId,
indexTemplates: templates,
}),
});

Expand Down
17 changes: 15 additions & 2 deletions server/routes/getting_started/getting_started_router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
SavedObject,
} from '../../../../../src/core/server';
import { createSavedObjectsStreamFromNdJson } from '../../../../../src/core/server/saved_objects/routes/utils';
import { loadAssetsFromFile } from './helper';
import { loadAssetsFromFile, createAllTemplatesSettled } from './helper';
import { getWorkspaceState } from '../../../../../src/core/server/utils';

export function registerGettingStartedRoutes(router: IRouter) {
Expand Down Expand Up @@ -140,6 +140,14 @@ export function registerGettingStartedRoutes(router: IRouter) {
mdsId: schema.string(),
mdsLabel: schema.string(),
tutorialId: schema.string(),
indexTemplates: schema.arrayOf(
schema.object({
name: schema.string(),
templatePath: schema.string(),
template: schema.recordOf(schema.string(), schema.any()),
}),
{ defaultValue: [] }
),
}),
},
},
Expand All @@ -149,10 +157,15 @@ export function registerGettingStartedRoutes(router: IRouter) {
response
): Promise<IOpenSearchDashboardsResponse<any | ResponseError>> => {
try {
const { mdsId, mdsLabel, tutorialId } = request.body;
const { mdsId, mdsLabel, tutorialId, indexTemplates } = request.body;
const { requestWorkspaceId } = getWorkspaceState(request);
const fileData = await loadAssetsFromFile(tutorialId);

// create related index templates
if (indexTemplates.length > 0) {
await createAllTemplatesSettled(context, indexTemplates, mdsId);
}

const objects = await createSavedObjectsStreamFromNdJson(Readable.from(fileData));
const loadedObjects = await objects.toArray();

Expand Down
45 changes: 45 additions & 0 deletions server/routes/getting_started/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import fs from 'fs';
import path from 'path';
import { MappingTypeMapping } from '@opensearch-project/opensearch/api/types';
import { RequestHandlerContext } from '../../../../../src/core/server';

export const assetMapper = (tutorialId: string) => {
switch (tutorialId) {
Expand Down Expand Up @@ -37,3 +39,46 @@ export const loadAssetsFromFile = async (tutorialId: string) => {
throw new Error('Issue is loading asset');
}
};

export const createAllTemplatesSettled = async (
context: RequestHandlerContext,
indexTemplates: Array<{ name: string; template: MappingTypeMapping; templatePath: string }>,
dataSourceMDSId: string
) => {
const results = await Promise.allSettled(
indexTemplates.map(({ name, template, templatePath }) =>
createIndexTemplate(context, name, template, dataSourceMDSId, templatePath)
)
);

return results.map((result, index) => {
const templateName = indexTemplates[index].name;
if (result.status === 'fulfilled') {
return { name: templateName, success: true };
}
return { name: templateName, success: false, reason: result.reason };
});
};

export const createIndexTemplate = async (
context: RequestHandlerContext,
name: string,
template: MappingTypeMapping,
dataSourceMDSId: string,
templatePath: string
) => {
try {
const osClient = dataSourceMDSId
? await context.dataSource.opensearch.getClient(dataSourceMDSId)
: context.core.opensearch.client.asCurrentUser;

return await osClient.transport.request({
method: 'PUT',
path: templatePath,
body: template,
});
} catch (error) {
console.error(`Failed to create index template ${name}:`, error);
throw error;
}
};

0 comments on commit 45f437f

Please sign in to comment.