Skip to content

Commit

Permalink
#335 Feature Request: GetMissions (#345)
Browse files Browse the repository at this point in the history
* #335 /configure/mission full param

* #335 touchup docs
  • Loading branch information
tariqksoliman authored Feb 23, 2023
1 parent 977f5be commit 1e992cf
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 42 deletions.
100 changes: 67 additions & 33 deletions API/Backend/Config/routes/configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ require("dotenv").config();
const express = require("express");
const router = express.Router();
const execFile = require("child_process").execFile;
const Sequelize = require("sequelize");
const { sequelize } = require("../../../connection");

const logger = require("../../../logger");
const Config = require("../models/config");
Expand Down Expand Up @@ -306,9 +308,11 @@ function upsert(req, res, next, cb, info) {
const { newlyAddedUUIDs, allNewUUIDs } = populateUUIDs(configJSON);

// Do not update the config if there are duplicate or bad UUIDs
const badUUIDs = newlyAddedUUIDs.filter(i => {
return 'replacesBadUUID' in i
}).map(i => i.replacesBadUUID);
const badUUIDs = newlyAddedUUIDs
.filter((i) => {
return "replacesBadUUID" in i;
})
.map((i) => i.replacesBadUUID);

if (badUUIDs.length > 0) {
if (cb)
Expand Down Expand Up @@ -374,7 +378,6 @@ function upsert(req, res, next, cb, info) {
newlyAddedUUIDs: newlyAddedUUIDs,
});


if (info && info.layerName) {
// Find the layer UUID instead of passing back the layer's display name
let isArray = true;
Expand All @@ -386,7 +389,9 @@ function upsert(req, res, next, cb, info) {
}

for (let i in infoLayerNames) {
const found = allNewUUIDs.findIndex(x => x.name == infoLayerNames[i]);
const found = allNewUUIDs.findIndex(
(x) => x.name == infoLayerNames[i]
);
if (found > -1) {
const result = allNewUUIDs[found];
infoLayerNames[i] = result.uuid;
Expand All @@ -395,7 +400,7 @@ function upsert(req, res, next, cb, info) {
}

if (!isArray) {
info.layerName = infoLayerNames[0]
info.layerName = infoLayerNames[0];
}
}

Expand Down Expand Up @@ -446,20 +451,36 @@ if (fullAccess)
});

router.get("/missions", function (req, res, next) {
Config.aggregate("mission", "DISTINCT", { plain: false })
.then((missions) => {
let allMissions = [];
for (let i = 0; i < missions.length; i++)
allMissions.push(missions[i].DISTINCT);
allMissions.sort();
res.send({ status: "success", missions: allMissions });
return null;
})
.catch((err) => {
logger("error", "Failed to find missions.", req.originalUrl, req, err);
res.send({ status: "failure", message: "Failed to find missions." });
return null;
});
if (req.query.full === "true") {
sequelize
.query(
"SELECT DISTINCT ON (mission) mission, version, config FROM configs ORDER BY mission ASC"
)
.spread((results) => {
res.send({ status: "success", missions: results });
return null;
})
.catch((err) => {
logger("error", "Failed to find missions.", req.originalUrl, req, err);
res.send({ status: "failure", message: "Failed to find missions." });
return null;
});
} else {
Config.aggregate("mission", "DISTINCT", { plain: false })
.then((missions) => {
let allMissions = [];
for (let i = 0; i < missions.length; i++)
allMissions.push(missions[i].DISTINCT);
allMissions.sort();
res.send({ status: "success", missions: allMissions });
return null;
})
.catch((err) => {
logger("error", "Failed to find missions.", req.originalUrl, req, err);
res.send({ status: "failure", message: "Failed to find missions." });
return null;
});
}
return null;
});

Expand Down Expand Up @@ -776,7 +797,7 @@ function addLayer(req, res, next, cb, forceConfig, caller = "addLayer") {
// user defined UUIDs. We remove the proposed_uuid key after using it to check for unique UUIDs.
Utils.traverseLayers([req.body.layer], (layer) => {
if (layer.uuid != null) {
layer.proposed_uuid = layer.uuid;
layer.proposed_uuid = layer.uuid;
}
});

Expand Down Expand Up @@ -826,8 +847,8 @@ function addLayer(req, res, next, cb, forceConfig, caller = "addLayer") {
{
type: caller,
layerName: Array.isArray(req.body.layer)
? req.body.layer.map(i => i.name)
: req.body.layer.name,
? req.body.layer.map((i) => i.name)
: req.body.layer.name,
}
);
} else if (cb)
Expand Down Expand Up @@ -1044,14 +1065,19 @@ function removeLayer(req, res, next, cb) {
}

let didRemove = false;
const removedUUIDs = Utils.traverseLayers(config.layers, (layer, path, index) => {
if (layerUUIDs.includes(layer.uuid)) {
didRemove = true;
return "remove";
const removedUUIDs = Utils.traverseLayers(
config.layers,
(layer, path, index) => {
if (layerUUIDs.includes(layer.uuid)) {
didRemove = true;
return "remove";
}
}
});
);

const unableToRemoveUUIDs = layerUUIDs.filter(i => !removedUUIDs.map(x => x.uuid).includes(i));
const unableToRemoveUUIDs = layerUUIDs.filter(
(i) => !removedUUIDs.map((x) => x.uuid).includes(i)
);
if (didRemove) {
upsert(
{
Expand All @@ -1067,27 +1093,35 @@ function removeLayer(req, res, next, cb) {
if (resp.status === "success") {
res.send({
status: "success",
message: `Successfully removed layer${removedUUIDs.length >= 1 ? 's' : ''}. Configuration versioned ${resp.version}.`,
message: `Successfully removed layer${
removedUUIDs.length >= 1 ? "s" : ""
}. Configuration versioned ${resp.version}.`,
removedUUIDs: removedUUIDs,
unableToRemoveUUIDs: unableToRemoveUUIDs,
});
} else {
res.send({
status: "failure",
message: `Failed to remove layer${layerUUIDs.length >= 1 ? 's' : ''}: ${resp.message}.`,
message: `Failed to remove layer${
layerUUIDs.length >= 1 ? "s" : ""
}: ${resp.message}.`,
unableToRemoveUUIDs: layerUUIDs,
});
}
},
{
type: "removeLayer",
layerName: layerUUIDs.filter(i => removedUUIDs.map(x => x.uuid).includes(i)),
layerName: layerUUIDs.filter((i) =>
removedUUIDs.map((x) => x.uuid).includes(i)
),
}
);
} else {
res.send({
status: "failure",
message: `Failed to remove layer${layerUUIDs.length >= 1 ? 's' : ''}. Layer${layerUUIDs.length >= 1 ? 's' : ''} not found.`,
message: `Failed to remove layer${
layerUUIDs.length >= 1 ? "s" : ""
}. Layer${layerUUIDs.length >= 1 ? "s" : ""} not found.`,
unableToRemoveUUIDs: layerUUIDs,
});
}
Expand Down
40 changes: 31 additions & 9 deletions docs/pages/APIs/Configure/Configure_REST_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,32 @@ To use the Configure API through HTTP requests, an API Token must be used for au

Gets a list of all configured missions. _Auth token not needed._

| Parameter | Type | Required | Default | Description |
| :-------: | :-------: | :------: | :-----: | :-------------------------------------------------------------------------: |
| **full** | _boolean_ | false | N/A | If true, returns versions and configuration objects alongside mission names |

#### Example

`curl -X GET http://localhost:8889/api/configure/missions`

```javascript
=> {status: "success", missions: ["Mission1", "Mission2"]}
```

`curl -X GET http://localhost:8889/api/configure/missions?full`

```javascript
=> {
status: "success",
missions: [
{
mission: "name", version: 99, config: {}
},
...
]
}
```

---

### GET /versions
Expand Down Expand Up @@ -111,12 +133,12 @@ Sets a mission's configuration object. Only complete configuration objects are a

Adds a single layer to a mission's configuration object. A wrapping helper to `upsert`.

| Parameter | Type | Required | Default | Description |
| Parameter | Type | Required | Default | Description |
| :-------------------: | :-----------------: | :------: | :-----: | :-------------------------------------------------------------------------------------------------------------------------------------------: |
| **mission** | _string_ | true | N/A | Mission name |
| **mission** | _string_ | true | N/A | Mission name |
| **layer** | _object_ or _array_ | true | N/A | Full new layer configuration object or array of full new layer configuration objects. See browser console-network tab responses for examples. |
| **placement.path** | _string_ | false | '' | A path to a header in 'layers' to place the new layer. A simple path ('sublayers' are added). Defaults to no group |
| **placement.index** | _number_ | false | end | Index in 'layers' (or path) to place the new layer. Out of range placement indices are best fit. |
| **placement.path** | _string_ | false | '' | A path to a header in 'layers' to place the new layer. A simple path ('sublayers' are added). Defaults to no group |
| **placement.index** | _number_ | false | end | Index in 'layers' (or path) to place the new layer. Out of range placement indices are best fit. |
| **forceClientUpdate** | _boolean_ | false | false | Push the change out to clients. |

#### Example
Expand Down Expand Up @@ -148,11 +170,11 @@ Updates a single layer. Specified layer values are deep merged and overwrite exi

Removes a single layer from the configuration object.

| Parameter | Type | Required | Default | Description |
| :-------------------: | :------------------: | :------: | :-----: | :--------------------------------------------------------------: |
| **mission** | _string_ | true | N/A | Mission name |
| **layerUUID** | _string_ or _array_ | true | N/A | Layer to remove as string or array of layers as string to remove |
| **forceClientUpdate** | _boolean_ | false | false | Push the change out to clients. |
| Parameter | Type | Required | Default | Description |
| :-------------------: | :-----------------: | :------: | :-----: | :--------------------------------------------------------------: |
| **mission** | _string_ | true | N/A | Mission name |
| **layerUUID** | _string_ or _array_ | true | N/A | Layer to remove as string or array of layers as string to remove |
| **forceClientUpdate** | _boolean_ | false | false | Push the change out to clients. |

#### Example

Expand Down

0 comments on commit 1e992cf

Please sign in to comment.