Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#335 Feature Request: GetMissions #345

Merged
merged 2 commits into from
Feb 23, 2023
Merged
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
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