Skip to content

Commit

Permalink
Validate connection object in CreateConnection endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
delfrrr committed May 19, 2024
1 parent c9dbaa4 commit ab17a43
Show file tree
Hide file tree
Showing 11 changed files with 656 additions and 591 deletions.
2 changes: 1 addition & 1 deletion cypress/e2e/google-oauth/testConnection.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe('basic query flow', () => {
// create connection
cy.get('button:contains("Create connection")').click()
const randomConnectionName = `test-${Math.floor(Math.random() * 1000000)}`
cy.get('div.ant-modal-title').should('contain', 'Edit Connection')
cy.get('div.ant-modal-title').should('contain', 'BigQuery')
cy.get('input#connectionName').clear()
cy.get('input#connectionName').type(randomConnectionName)
cy.get('input#bigqueryProjectId').type('dekart-dev')
Expand Down
2 changes: 1 addition & 1 deletion proto/dekart.proto
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ message UpdateConnectionResponse {
}

message CreateConnectionRequest {
string connection_name = 1;
Connection connection = 1;
}

message CreateConnectionResponse {
Expand Down
28 changes: 19 additions & 9 deletions src/client/ConnectionModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Button from 'antd/es/button'
import styles from './ConnectionModal.module.css'
import { useEffect } from 'react'
import { archiveConnection, closeConnectionDialog, connectionChanged, saveConnection, testConnection } from './actions/connection'
import { CheckCircleTwoTone, ExclamationCircleTwoTone } from '@ant-design/icons'
import { CheckCircleTwoTone, ExclamationCircleTwoTone, LoadingOutlined } from '@ant-design/icons'
import Tooltip from 'antd/es/tooltip'
import AutoComplete from 'antd/es/auto-complete'
import Alert from 'antd/es/alert'
Expand Down Expand Up @@ -44,7 +44,7 @@ function Footer ({ form }) {
>
Save
</Button>
<Button onClick={() => dispatch(archiveConnection(id))}>
<Button disabled={!id} onClick={() => dispatch(archiveConnection(id))}>
Archive
</Button>
</div>
Expand Down Expand Up @@ -81,7 +81,7 @@ export default function ConnectionModal () {
return (
<Modal
open
title='Edit Connection'
title='BigQuery'
onCancel={() => dispatch(closeConnectionDialog())}
footer={<Footer form={form} />}
>
Expand All @@ -98,24 +98,34 @@ export default function ConnectionModal () {
}
}}
>
{connection?.datasetCount > 0 ? <div className={styles.datasetsCountAlert}><Alert message={<>Danger zone! This connection is used in {connection.datasetCount} dataset{connection.datasetCount > 1 ? 's' : ''}.</>} description="Modifying it may lead to queries and results not being found in reports. Consider creating new connection and archiving this one. Modifying name is safe." type="error" /></div> : null}
<Form.Item label='Google Cloud project ID' extra='used to bill BigQuery jobs' required name='bigqueryProjectId'>
{connection?.datasetCount > 0 ? <div className={styles.datasetsCountAlert}><Alert message={<>Danger zone! This connection is used in {connection.datasetCount} dataset{connection.datasetCount > 1 ? 's' : ''}.</>} description='Modifying it may lead to queries and results not being found in reports. Consider creating new connection and archiving this one. Modifying name is safe.' type='error' /></div> : null}
<Form.Item
label='Project ID' extra={(() => {
if (projects && !BIGQUERY_PROJECT_ID) {
return projects.length ? 'Click to select you BigQuery project ID' : <><a target='_blank' href='https://dekart.xyz/docs/configuration/environment-variables/?ref=no-gcp-project#user-authorization-via-google-oauth-20-flow' rel='noreferrer'>Ensure your account has access to the Google Cloud Project</a></>
}
return <LoadingOutlined />
})()} required name='bigqueryProjectId'
>
{
projects.length > 0 && !BIGQUERY_PROJECT_ID
projects?.length > 0 && !BIGQUERY_PROJECT_ID
? (
<AutoComplete
options={projects.map(project => ({ value: project, label: project }))}
options={(projects || []).map(project => ({ value: project, label: project }))}
// suffixIcon={<DownOutlined />}
showArrow
filterOption={(inputValue, option) => option.value.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1}
/>

)
: <Input readOnly={BIGQUERY_PROJECT_ID} />
}
</Form.Item>
<Form.Item label='Connection Name' required name='connectionName'>
<Input />
</Form.Item>
<Form.Item label='Optional Google Cloud Storage bucket' extra='to store files and result cache ' name='cloudStorageBucket'>
<Input placeholder='my-company-storage-bucket' readOnly={CLOUD_STORAGE_BUCKET} />
<Form.Item label='Optional: query cache bucket' extra={<>Google Cloud Storage bucket to permanently cache query results. When not provided, query results are read from <a href='https://cloud.google.com/bigquery/docs/cached-results' target='_blank' rel='noreferrer'>BigQuery result cache</a></>} name='cloudStorageBucket'>
<Input placeholder='my-gcs-bucket' readOnly={CLOUD_STORAGE_BUCKET} />
</Form.Item>
</Form>
</div>
Expand Down
1 change: 0 additions & 1 deletion src/client/Dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ function DatasetTypeSelector ({ dataset }) {
}
}


return (
<div className={styles.datasetTypeSelector}>
<Dropdown
Expand Down
56 changes: 31 additions & 25 deletions src/client/actions/connection.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ArchiveConnectionRequest, CreateConnectionRequest, GetConnectionListRequest, Connection, TestConnectionRequest, UpdateConnectionRequest, SetDefaultConnectionRequest, GetGcpProjectListRequest } from '../../proto/dekart_pb'
import { Dekart } from '../../proto/dekart_pb_service'
import { updateDatasetConnection } from './dataset'
import { grpcCall } from './grpc'

export function connectionCreated ({ id, connectionName }) {
Expand Down Expand Up @@ -74,19 +73,10 @@ export function archiveConnection (id) {
}
}

export function newConnection (datasetId) {
return async (dispatch, getState) => {
export function newConnection () {
return async (dispatch) => {
// just to show the modal
dispatch({ type: newConnection.name })

const request = new CreateConnectionRequest()

const res = await new Promise((resolve) => {
dispatch(grpcCall(Dekart.CreateConnection, request, resolve))
})
if (datasetId) {
dispatch(updateDatasetConnection(datasetId, res.connection.id))
}
dispatch(connectionCreated(res.connection))
dispatch(getProjectList())
}
}
Expand Down Expand Up @@ -116,18 +106,34 @@ export function connectionSaved () {
export function saveConnection (id, connectionProps) {
return async (dispatch, getState) => {
dispatch({ type: saveConnection.name })

const request = new UpdateConnectionRequest()
const connection = new Connection()
connection.setId(id)
connection.setConnectionName(connectionProps.connectionName)
connection.setBigqueryProjectId(connectionProps.bigqueryProjectId)
connection.setCloudStorageBucket(connectionProps.cloudStorageBucket)
request.setConnection(connection)

await new Promise((resolve) => {
dispatch(grpcCall(Dekart.UpdateConnection, request, resolve))
})
if (!id) {
// create new connection
const request = new CreateConnectionRequest()
const connection = new Connection()
connection.setConnectionName(connectionProps.connectionName)
connection.setBigqueryProjectId(connectionProps.bigqueryProjectId)
connection.setCloudStorageBucket(connectionProps.cloudStorageBucket)
request.setConnection(connection)

const res = await new Promise((resolve) => {
dispatch(grpcCall(Dekart.CreateConnection, request, resolve))
})

dispatch(connectionCreated(res.connection))
} else {
// update existing connection
const request = new UpdateConnectionRequest()
const connection = new Connection()
connection.setId(id)
connection.setConnectionName(connectionProps.connectionName)
connection.setBigqueryProjectId(connectionProps.bigqueryProjectId)
connection.setCloudStorageBucket(connectionProps.cloudStorageBucket)
request.setConnection(connection)

await new Promise((resolve) => {
dispatch(grpcCall(Dekart.UpdateConnection, request, resolve))
})
}

dispatch(connectionSaved())
}
Expand Down
4 changes: 2 additions & 2 deletions src/client/reducers/connectionReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function dialog (state = {
...state,
visible: true,
id: null,
loading: true
loading: false
}
case connectionCreated.name:
return {
Expand Down Expand Up @@ -114,7 +114,7 @@ function userDefined (state = false, action) {
}
}

function projects (state = [], action) {
function projects (state = null, action) {
switch (action.type) {
case projectListUpdate.name:
return action.projectsList
Expand Down
Loading

0 comments on commit ab17a43

Please sign in to comment.