Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/graph-explorer-proxy-server/src/node-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface DbQueryIncomingHttpHeaders extends IncomingHttpHeaders {
"aws-neptune-region"?: string;
"service-type"?: string;
"db-query-logging-enabled"?: string;
"sparql-endpoint-path"?: string;
}

interface LoggerIncomingHttpHeaders extends IncomingHttpHeaders {
Expand Down Expand Up @@ -202,6 +203,7 @@ app.post("/sparql", async (req, res, next) => {
const headers = req.headers as DbQueryIncomingHttpHeaders;
const queryId = headers["queryid"];
const graphDbConnectionUrl = headers["graph-db-connection-url"];
const sparqlEndpointPath = headers["sparql-endpoint-path"] || "/sparql";
const shouldLogDbQuery = BooleanStringSchema.default(false).parse(
headers["db-query-logging-enabled"],
);
Expand All @@ -219,7 +221,7 @@ app.post("/sparql", async (req, res, next) => {
proxyLogger.debug(`Cancelling request ${queryId}...`);
try {
await retryFetch(
new URL(`${graphDbConnectionUrl}/sparql/status`),
new URL(`${graphDbConnectionUrl}${sparqlEndpointPath}/status`),
{
method: "POST",
headers: {
Expand Down Expand Up @@ -264,7 +266,7 @@ app.post("/sparql", async (req, res, next) => {
proxyLogger.debug("[SPARQL] Received database query:\n%s", queryString);
}

const rawUrl = `${graphDbConnectionUrl}/sparql`;
const rawUrl = `${graphDbConnectionUrl}${sparqlEndpointPath}`;
let body = `query=${encodeURIComponent(queryString)}`;
if (queryId) {
body += `&queryId=${encodeURIComponent(queryId)}`;
Expand Down
3 changes: 3 additions & 0 deletions packages/graph-explorer/src/connector/fetchDatabaseRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ function getAuthHeaders(
headers["db-query-logging-enabled"] = String(
featureFlags.allowLoggingDbQuery,
);
if (connection.sparqlEndpointPath) {
headers["sparql-endpoint-path"] = connection.sparqlEndpointPath;
}
}
if (connection.awsAuthEnabled) {
headers["aws-neptune-region"] = connection.awsRegion || "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function _sparqlFetch(
return fetchDatabaseRequest(
connection,
featureFlags,
`${connection.url}/sparql`,
`${connection.url}${connection.sparqlEndpointPath ?? "/sparql"}`,
{
method: "POST",
headers,
Expand Down
3 changes: 3 additions & 0 deletions packages/graph-explorer/src/core/defaultConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export const DefaultConnectionDataSchema = z.object({
.enum(neptuneServiceTypeOptions)
.default(DEFAULT_SERVICE_TYPE)
.catch(DEFAULT_SERVICE_TYPE),
// SPARQL options
GRAPH_EXP_SPARQL_ENDPOINT_PATH: z.string().optional(),
// Connection options
GRAPH_EXP_FETCH_REQUEST_TIMEOUT: z.number().default(240000),
GRAPH_EXP_NODE_EXPANSION_LIMIT: z.number().optional(),
Expand Down Expand Up @@ -116,6 +118,7 @@ export function mapToConnection(data: DefaultConnectionData): RawConfiguration {
awsAuthEnabled: data.GRAPH_EXP_IAM,
awsRegion: data.GRAPH_EXP_AWS_REGION,
serviceType: data.GRAPH_EXP_SERVICE_TYPE,
sparqlEndpointPath: data.GRAPH_EXP_SPARQL_ENDPOINT_PATH,
fetchTimeoutMs: data.GRAPH_EXP_FETCH_REQUEST_TIMEOUT,
nodeExpansionLimit: data.GRAPH_EXP_NODE_EXPANSION_LIMIT,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type ConnectionForm = {
awsAuthEnabled?: boolean;
serviceType?: NeptuneServiceType;
awsRegion?: string;
sparqlEndpointPath?: string;
fetchTimeoutEnabled: boolean;
fetchTimeoutMs?: number;
nodeExpansionLimitEnabled: boolean;
Expand Down Expand Up @@ -72,6 +73,7 @@ function mapToConnection(data: Required<ConnectionForm>): ConnectionConfig {
awsAuthEnabled: data.awsAuthEnabled,
serviceType: data.serviceType,
awsRegion: data.awsRegion,
sparqlEndpointPath: data.sparqlEndpointPath || undefined,
fetchTimeoutMs: data.fetchTimeoutEnabled ? data.fetchTimeoutMs : undefined,
nodeExpansionLimit: data.nodeExpansionLimitEnabled
? data.nodeExpansionLimit
Expand Down Expand Up @@ -275,6 +277,25 @@ const CreateConnection = ({
disabled={form.serviceType === "neptune-graph"}
/>
</FormItem>
{form.queryEngine === "sparql" && (
<FormItem>
<Label>
SPARQL Endpoint Path
<InfoTooltip>
The path appended to the connection URL for SPARQL queries.
Defaults to &quot;/sparql&quot;. Some triple stores use
different paths, e.g., Apache Jena Fuseki uses
&quot;/query&quot;.
</InfoTooltip>
</Label>
<InputField
aria-label="SPARQL Endpoint Path"
value={form.sparqlEndpointPath ?? ""}
onChange={onFormChange("sparqlEndpointPath")}
placeholder="/sparql"
/>
</FormItem>
)}
<FormItem>
<Label>
Public or Proxy Endpoint
Expand Down
6 changes: 6 additions & 0 deletions packages/shared/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ export type ConnectionConfig = {
* It is needed to sign requests.
*/
awsRegion?: string;
/**
* Custom SPARQL endpoint path appended to the connection URL.
* By default, "/sparql". Some triple stores use different paths,
* e.g., Apache Jena Fuseki uses "/query".
*/
sparqlEndpointPath?: string;
/**
* Number of milliseconds before aborting a request.
* By default, undefined.
Expand Down