mirror of https://gitee.com/bigwinds/arangodb
Fix Foxx API (#4614)
This commit is contained in:
parent
1c80774091
commit
cd97787adf
11
CHANGELOG
11
CHANGELOG
|
@ -1,7 +1,12 @@
|
||||||
devel
|
devel
|
||||||
-----
|
-----
|
||||||
|
|
||||||
* renamed startup option `--replication.automatic-failover` to
|
* fixed Foxx API:
|
||||||
|
|
||||||
|
* PUT /_api/foxx/service: Respect force flag
|
||||||
|
* PATCH /_api/foxx/service: Check whether a service under given mount exists
|
||||||
|
|
||||||
|
* renamed startup option `--replication.automatic-failover` to
|
||||||
`--replication.active-failover`
|
`--replication.active-failover`
|
||||||
using the old option name will still work in ArangoDB 3.4, but the old option
|
using the old option name will still work in ArangoDB 3.4, but the old option
|
||||||
will be removed afterwards
|
will be removed afterwards
|
||||||
|
@ -12,7 +17,7 @@ devel
|
||||||
inaccurate estimates. The issue is solved now, but there can be up to a second
|
inaccurate estimates. The issue is solved now, but there can be up to a second
|
||||||
or so delay before updates are reflected in the estimates.
|
or so delay before updates are reflected in the estimates.
|
||||||
|
|
||||||
* support `returnOld` and `returnNew` attributes for in the following HTTP REST
|
* support `returnOld` and `returnNew` attributes for in the following HTTP REST
|
||||||
APIs:
|
APIs:
|
||||||
|
|
||||||
* /_api/gharial/<graph>/vertex/<collection>
|
* /_api/gharial/<graph>/vertex/<collection>
|
||||||
|
@ -21,7 +26,7 @@ devel
|
||||||
The exception from this is that the HTTP DELETE verb for these APIs does not
|
The exception from this is that the HTTP DELETE verb for these APIs does not
|
||||||
support `returnOld` because that would make the existing API incompatible
|
support `returnOld` because that would make the existing API incompatible
|
||||||
|
|
||||||
* fixed issue #4160: Run arangod with "--database.auto-upgrade" option always crash
|
* fixed issue #4160: Run arangod with "--database.auto-upgrade" option always crash
|
||||||
silently without error log
|
silently without error log
|
||||||
|
|
||||||
* fix issue #4457: create /var/tmp/arangod with correct user in supervisor mode
|
* fix issue #4457: create /var/tmp/arangod with correct user in supervisor mode
|
||||||
|
|
|
@ -53,6 +53,9 @@ Set to `false` to not run the new service's setup script.
|
||||||
@RESTQUERYPARAM{legacy,boolean,optional}
|
@RESTQUERYPARAM{legacy,boolean,optional}
|
||||||
Set to `true` to install the new service in 2.8 legacy compatibility mode.
|
Set to `true` to install the new service in 2.8 legacy compatibility mode.
|
||||||
|
|
||||||
|
@RESTQUERYPARAM{force,boolean,optional}
|
||||||
|
Set to `true` to force service install even if no service is installed under given mount.
|
||||||
|
|
||||||
@RESTRETURNCODES
|
@RESTRETURNCODES
|
||||||
|
|
||||||
@RESTRETURNCODE{200}
|
@RESTRETURNCODE{200}
|
||||||
|
|
|
@ -199,6 +199,7 @@ serviceRouter.put(prepareServiceRequestBody, (req, res) => {
|
||||||
.queryParam('teardown', schemas.flag.default(true))
|
.queryParam('teardown', schemas.flag.default(true))
|
||||||
.queryParam('setup', schemas.flag.default(true))
|
.queryParam('setup', schemas.flag.default(true))
|
||||||
.queryParam('legacy', schemas.flag.default(false))
|
.queryParam('legacy', schemas.flag.default(false))
|
||||||
|
.queryParam('force', schemas.flag.default(false))
|
||||||
.response(200, schemas.fullInfo);
|
.response(200, schemas.fullInfo);
|
||||||
|
|
||||||
serviceRouter.delete((req, res) => {
|
serviceRouter.delete((req, res) => {
|
||||||
|
|
|
@ -1288,8 +1288,8 @@ describe('Foxx service', () => {
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
['GET', '/_api/foxx/service'],
|
['GET', '/_api/foxx/service'],
|
||||||
['PATCH', '/_api/foxx/service'],
|
['PATCH', '/_api/foxx/service', { source: servicePath }],
|
||||||
['PUT', '/_api/foxx/service'],
|
['PUT', '/_api/foxx/service', { source: servicePath }],
|
||||||
['DELETE', '/_api/foxx/service'],
|
['DELETE', '/_api/foxx/service'],
|
||||||
['GET', '/_api/foxx/configuration'],
|
['GET', '/_api/foxx/configuration'],
|
||||||
['PATCH', '/_api/foxx/configuration'],
|
['PATCH', '/_api/foxx/configuration'],
|
||||||
|
@ -1306,20 +1306,22 @@ describe('Foxx service', () => {
|
||||||
['GET', '/_api/foxx/readme'],
|
['GET', '/_api/foxx/readme'],
|
||||||
['GET', '/_api/foxx/swagger']
|
['GET', '/_api/foxx/swagger']
|
||||||
];
|
];
|
||||||
for (const [method, url] of routes) {
|
for (const [method, url, body] of routes) {
|
||||||
it(`should return 400 when mount is omitted for ${method} ${url}`, () => {
|
it(`should return 400 when mount is omitted for ${method} ${url}`, () => {
|
||||||
const resp = request({
|
const resp = request({
|
||||||
method,
|
method,
|
||||||
url,
|
url,
|
||||||
|
body,
|
||||||
json: true
|
json: true
|
||||||
});
|
});
|
||||||
expect(resp.status).to.equal(400);
|
expect(resp.status).to.equal(400);
|
||||||
});
|
});
|
||||||
it(`should return 400 when mount is invalid for ${method} ${url}`, () => {
|
it(`should return 400 when mount is unknown for ${method} ${url}`, () => {
|
||||||
const resp = request({
|
const resp = request({
|
||||||
method,
|
method,
|
||||||
url,
|
url,
|
||||||
qs: {mount: '/dev/null'},
|
qs: {mount: '/dev/null'},
|
||||||
|
body,
|
||||||
json: true
|
json: true
|
||||||
});
|
});
|
||||||
expect(resp.status).to.equal(400);
|
expect(resp.status).to.equal(400);
|
||||||
|
@ -1337,4 +1339,36 @@ describe('Foxx service', () => {
|
||||||
expect(resp.json).to.have.property('failures');
|
expect(resp.json).to.have.property('failures');
|
||||||
expect(resp.json).to.have.property('passes');
|
expect(resp.json).to.have.property('passes');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('replace on invalid mount should not be installed', () => {
|
||||||
|
const replaceResp = request.put('/_api/foxx/service', {
|
||||||
|
qs: {
|
||||||
|
mount
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
source: servicePath
|
||||||
|
},
|
||||||
|
json: true
|
||||||
|
});
|
||||||
|
expect(replaceResp.status).to.equal(400);
|
||||||
|
const resp = request.get(mount);
|
||||||
|
expect(resp.status).to.equal(404);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('replace on invalid mount should be installed when forced', () => {
|
||||||
|
const replaceResp = request.put('/_api/foxx/service', {
|
||||||
|
qs: {
|
||||||
|
mount,
|
||||||
|
force: true
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
source: servicePath
|
||||||
|
},
|
||||||
|
json: true
|
||||||
|
});
|
||||||
|
expect(replaceResp.status).to.equal(200);
|
||||||
|
const resp = request.get(mount);
|
||||||
|
expect(resp.status).to.equal(200);
|
||||||
|
expect(resp.json).to.eql({hello: 'world'});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -860,8 +860,21 @@ function uninstall (mount, options = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function replace (serviceInfo, mount, options = {}) {
|
function replace (serviceInfo, mount, options = {}) {
|
||||||
utils.validateMount(mount);
|
|
||||||
ensureFoxxInitialized();
|
ensureFoxxInitialized();
|
||||||
|
if (!options.force) {
|
||||||
|
const serviceDefinition = utils.getServiceDefinition(mount);
|
||||||
|
if (!serviceDefinition) {
|
||||||
|
throw new ArangoError({
|
||||||
|
errorNum: errors.ERROR_SERVICE_NOT_FOUND.code,
|
||||||
|
errorMessage: dd`
|
||||||
|
${errors.ERROR_SERVICE_NOT_FOUND.message}
|
||||||
|
Mount path: "${mount}".
|
||||||
|
`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
utils.validateMount(mount);
|
||||||
|
}
|
||||||
const tempPaths = _prepareService(serviceInfo, options);
|
const tempPaths = _prepareService(serviceInfo, options);
|
||||||
FoxxService.validatedManifest({
|
FoxxService.validatedManifest({
|
||||||
mount,
|
mount,
|
||||||
|
@ -877,7 +890,17 @@ function replace (serviceInfo, mount, options = {}) {
|
||||||
|
|
||||||
function upgrade (serviceInfo, mount, options = {}) {
|
function upgrade (serviceInfo, mount, options = {}) {
|
||||||
ensureFoxxInitialized();
|
ensureFoxxInitialized();
|
||||||
const serviceOptions = utils.getServiceDefinition(mount).options;
|
const serviceDefinition = utils.getServiceDefinition(mount);
|
||||||
|
if (!serviceDefinition) {
|
||||||
|
throw new ArangoError({
|
||||||
|
errorNum: errors.ERROR_SERVICE_NOT_FOUND.code,
|
||||||
|
errorMessage: dd`
|
||||||
|
${errors.ERROR_SERVICE_NOT_FOUND.message}
|
||||||
|
Mount path: "${mount}".
|
||||||
|
`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const serviceOptions = serviceDefinition.options;
|
||||||
Object.assign(serviceOptions.configuration, options.configuration);
|
Object.assign(serviceOptions.configuration, options.configuration);
|
||||||
Object.assign(serviceOptions.dependencies, options.dependencies);
|
Object.assign(serviceOptions.dependencies, options.dependencies);
|
||||||
serviceOptions.development = options.development;
|
serviceOptions.development = options.development;
|
||||||
|
|
Loading…
Reference in New Issue