diff --git a/README.md b/README.md index 397aacb..1527343 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,27 @@ npm install @zeit/cosmosdb-server It exposes the `cosmosdb-server` cli command as well. +### Setup for Java + +Add the certificate to the Java CA certificates store like the following: + +```sh +# Example for MacOS. Adjust paths and command according to your environment. +sudo keytool -keystore "$JAVA_HOME/jre/lib/security/cacerts" -importcert -alias vercel-cosmosdb-server -file node_modules/@zeit/cosmosdb-server/cert.pem +``` + +Also ensure to use Gateway mode for the connection policy since this server doesn't support Direct mode: + +```java +import com.azure.cosmos.ConnectionMode; +import com.azure.cosmos.ConnectionPolicy + +... + +ConnectionPolicy policy = ConnectionPolicy.getDefaultPolicy(); +policy.setConnectionMode(ConnectionMode.GATEWAY); +``` + ## API #### cosmosServer(opts?: https.ServerOptions): https.Server diff --git a/src/account/index.ts b/src/account/index.ts index ae6c527..3d5ca59 100644 --- a/src/account/index.ts +++ b/src/account/index.ts @@ -1,18 +1,52 @@ /* eslint-disable class-methods-use-this, no-underscore-dangle */ import Databases from "./databases"; import Item from "./item"; +import ItemObject from "./item-object"; export default class Account extends Item { databases: Databases; - constructor() { + constructor(port: number) { super({ - id: "", - _etag: "", - _rid: "", + _rid: "localhost", _self: "", - _ts: 0 - }); + _dbs: "//dbs/", + id: "localhost", + media: "//media/", + addresses: "//addresses/", + writableLocations: [ + { + name: "South Central US", + databaseAccountEndpoint: `https://localhost:${port}/` + } + ], + readableLocations: [ + { + name: "South Central US", + databaseAccountEndpoint: `https://localhost:${port}/` + } + ], + enableMultipleWriteLocations: false, + userReplicationPolicy: { + asyncReplication: false, + minReplicaSetSize: 1, + maxReplicasetSize: 4 + }, + userConsistencyPolicy: { + defaultConsistencyLevel: "Session" + }, + systemReplicationPolicy: { + minReplicaSetSize: 1, + maxReplicasetSize: 4 + }, + readPolicy: { + primaryReadCoefficient: 1, + secondaryReadCoefficient: 1 + }, + queryEngineConfiguration: + '{"maxSqlQueryInputLength":262144,"maxJoinsPerSqlQuery":5,"maxLogicalAndPerSqlQuery":500,"maxLogicalOrPerSqlQuery":500,"maxUdfRefPerSqlQuery":10,"maxInExpressionItemsCount":16000,"queryMaxInMemorySortDocumentCount":500,"maxQueryRequestTimeoutFraction":0.9,"sqlAllowNonFiniteNumbers":false,"sqlAllowAggregateFunctions":true,"sqlAllowSubQuery":true,"sqlAllowScalarSubQuery":true,"allowNewKeywords":true,"sqlAllowLike":false,"maxSpatialQueryCells":12,"spatialMaxGeometryPointCount":256,"sqlAllowTop":true,"enableSpatialIndexing":true}' + } as ItemObject); + this.databases = new Databases(this); } diff --git a/src/account/item-object.ts b/src/account/item-object.ts index 66b0ad1..53fa663 100644 --- a/src/account/item-object.ts +++ b/src/account/item-object.ts @@ -8,10 +8,10 @@ type ItemObject = { partitionKey?: { paths: string[]; }; - _etag: string; + _etag?: string; _rid: string; _self: string; - _ts: number; + _ts?: number; }; // eslint-disable-next-line no-undef diff --git a/src/handler/read-account.ts b/src/handler/read-account.ts new file mode 100644 index 0000000..e795f45 --- /dev/null +++ b/src/handler/read-account.ts @@ -0,0 +1,3 @@ +import Account from "../account"; + +export default (account: Account) => account.read(); diff --git a/src/handler/read-addresses.ts b/src/handler/read-addresses.ts new file mode 100644 index 0000000..e6fb6cd --- /dev/null +++ b/src/handler/read-addresses.ts @@ -0,0 +1,11 @@ +import * as http from "http"; +import Account from "../account"; + +export default ( + account: Account, + req: http.IncomingMessage, + res: http.ServerResponse +) => { + res.statusCode = 501; + return { Message: "Not implemented" }; +}; diff --git a/src/handler/read-meta.ts b/src/handler/read-meta.ts deleted file mode 100644 index 56bf55f..0000000 --- a/src/handler/read-meta.ts +++ /dev/null @@ -1 +0,0 @@ -export default () => ({}); diff --git a/src/index.ts b/src/index.ts index d1a1469..1630390 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,9 +15,9 @@ const options: ServerOptions = { }; export default (opts?: ServerOptions) => { - const account = new Account(); + let account: Account | undefined; - return createServer({...options, ...opts}, (req, res) => { + const server = createServer({ ...options, ...opts }, (req, res) => { const route = routes(req); (async () => { @@ -59,5 +59,14 @@ export default (opts?: ServerOptions) => { res.end(""); } }); + }).on("listening", () => { + const address = server.address(); + if (typeof address === "object" && address) { + account = new Account(address.port); + } else { + throw new Error(`Unexpected address type: ${address}`); + } }); + + return server; }; diff --git a/src/routes.ts b/src/routes.ts index fd6fdc3..a4170ce 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -10,13 +10,14 @@ import queryCollections from "./handler/query-collections"; import queryDatabases from "./handler/query-databases"; import queryDocuments from "./handler/query-documents"; import queryUserDefinedFunctions from "./handler/query-user-defined-functions"; +import readAccount from "./handler/read-account"; +import readAddresses from "./handler/read-addresses"; import readCollection from "./handler/read-collection"; import readCollections from "./handler/read-collections"; import readDatabase from "./handler/read-database"; import readDatabases from "./handler/read-databases"; import readDocument from "./handler/read-document"; import readDocuments from "./handler/read-documents"; -import readMeta from "./handler/read-meta"; import readPartitionKeyRanges from "./handler/read-partition-key-ranges"; import readUserDefinedFunction from "./handler/read-user-defined-function"; import readUserDefinedFunctions from "./handler/read-user-defined-functions"; @@ -35,6 +36,7 @@ export default router({ "/dbs/:dbId": deleteDatabase }, GET: { + "/addresses": readAddresses, "/dbs/:dbId/colls/:collId/docs/:docId": readDocument, "/dbs/:dbId/colls/:collId/docs": readDocuments, "/dbs/:dbId/colls/:collId/pkranges": readPartitionKeyRanges, @@ -44,7 +46,7 @@ export default router({ "/dbs/:dbId/colls": readCollections, "/dbs/:dbId": readDatabase, "/dbs": readDatabases, - "/": readMeta + "/": readAccount }, POST: { "/dbs/:dbId/colls/:collId/docs": createDocument, diff --git a/test/sdk.sh b/test/sdk.sh index ad4c759..5b4bec0 100755 --- a/test/sdk.sh +++ b/test/sdk.sh @@ -15,4 +15,4 @@ npm run build:test -- --force mv src/tsconfig.json{.bak,} ACCOUNT_HOST="https://localhost:$port" npm run integration-test:node -- --i --exit \ - -g 'Authorization|database account|http proxy|Change Feed|Cross Partition|indexing|Offer CRUD|Parallel Query As String|Permission|Query Metrics On Single Partition Collection|ResourceLink Trimming|Session Token|spatial|sproc|stored procedure|Trigger|trigger|TTL|User|Non Partitioned|Validate SSL verification|matching constant version & package version' + -g 'Authorization|http proxy|Change Feed|Cross Partition|indexing|Offer CRUD|Parallel Query As String|Permission|Query Metrics On Single Partition Collection|ResourceLink Trimming|Session Token|spatial|sproc|stored procedure|Trigger|trigger|TTL|User|Non Partitioned|Validate SSL verification|matching constant version & package version'