summaryrefslogtreecommitdiff
path: root/src/sagas
diff options
context:
space:
mode:
authorGeorgios Andreadis <g.andreadis@student.tudelft.nl>2017-08-25 17:48:12 +0200
committerGeorgios Andreadis <g.andreadis@student.tudelft.nl>2017-09-23 10:05:44 +0200
commitc47a27b826f7d76410308a4151611a366f9eaf46 (patch)
treec1ca374204714cedabcacb8620848b903a0bf8d6 /src/sagas
parent1ddbbd3563af77a218020021ea50a8832900b4db (diff)
Fetch and display datacenter topology
Diffstat (limited to 'src/sagas')
-rw-r--r--src/sagas/index.js18
-rw-r--r--src/sagas/objects.js109
-rw-r--r--src/sagas/profile.js12
-rw-r--r--src/sagas/simulations.js30
-rw-r--r--src/sagas/topology.js71
-rw-r--r--src/sagas/users.js46
6 files changed, 286 insertions, 0 deletions
diff --git a/src/sagas/index.js b/src/sagas/index.js
new file mode 100644
index 00000000..c6177cd4
--- /dev/null
+++ b/src/sagas/index.js
@@ -0,0 +1,18 @@
+import {takeEvery} from "redux-saga/effects";
+import {LOG_IN} from "../actions/auth";
+import {ADD_SIMULATION, DELETE_SIMULATION} from "../actions/simulations";
+import {FETCH_LATEST_DATACENTER} from "../actions/topology";
+import {DELETE_CURRENT_USER, FETCH_AUTHORIZATIONS_OF_CURRENT_USER} from "../actions/users";
+import {onDeleteCurrentUser} from "./profile";
+import {onSimulationAdd, onSimulationDelete} from "./simulations";
+import {onFetchLatestDatacenter} from "./topology";
+import {onFetchAuthorizationsOfCurrentUser, onFetchLoggedInUser} from "./users";
+
+export default function* rootSaga() {
+ yield takeEvery(LOG_IN, onFetchLoggedInUser);
+ yield takeEvery(FETCH_AUTHORIZATIONS_OF_CURRENT_USER, onFetchAuthorizationsOfCurrentUser);
+ yield takeEvery(ADD_SIMULATION, onSimulationAdd);
+ yield takeEvery(DELETE_SIMULATION, onSimulationDelete);
+ yield takeEvery(DELETE_CURRENT_USER, onDeleteCurrentUser);
+ yield takeEvery(FETCH_LATEST_DATACENTER, onFetchLatestDatacenter);
+}
diff --git a/src/sagas/objects.js b/src/sagas/objects.js
new file mode 100644
index 00000000..5fac6c3e
--- /dev/null
+++ b/src/sagas/objects.js
@@ -0,0 +1,109 @@
+import {call, put, select} from "redux-saga/effects";
+import {addToStore} from "../actions/objects";
+import {getDatacenter, getRoomsOfDatacenter} from "../api/routes/datacenters";
+import {getPath, getSectionsOfPath} from "../api/routes/paths";
+import {getTilesOfRoom} from "../api/routes/rooms";
+import {getSection} from "../api/routes/sections";
+import {getPathsOfSimulation, getSimulation} from "../api/routes/simulations";
+import {
+ getCoolingItem,
+ getCPU,
+ getFailureModel,
+ getGPU,
+ getMemory,
+ getPSU,
+ getStorage
+} from "../api/routes/specifications";
+import {getMachinesOfRackByTile, getRackByTile} from "../api/routes/tiles";
+import {getUser} from "../api/routes/users";
+
+export const OBJECT_SELECTORS = {
+ simulation: state => state.objects.simulation,
+ user: state => state.objects.user,
+ authorization: state => state.objects.authorization,
+ failureModel: state => state.objects.failureModel,
+ cpu: state => state.objects.cpu,
+ gpu: state => state.objects.gpu,
+ memory: state => state.objects.memory,
+ storage: state => state.objects.storage,
+ machine: state => state.objects.machine,
+ rack: state => state.objects.rack,
+ coolingItem: state => state.objects.coolingItem,
+ psu: state => state.objects.psu,
+ tile: state => state.objects.tile,
+ room: state => state.objects.room,
+ datacenter: state => state.objects.datacenter,
+ section: state => state.objects.section,
+ path: state => state.objects.path,
+};
+
+function* fetchAndStoreObject(objectType, id, apiCall) {
+ const objectStore = yield select(OBJECT_SELECTORS[objectType]);
+ if (!objectStore[id]) {
+ const object = yield apiCall;
+ yield put(addToStore(objectType, object));
+ }
+ return objectStore[id];
+}
+
+function* fetchAndStoreObjects(objectType, apiCall) {
+ const objects = yield apiCall;
+ for (let index in objects) {
+ yield put(addToStore(objectType, objects[index]));
+ }
+ return objects;
+}
+
+export const fetchAndStoreSimulation = (id) =>
+ fetchAndStoreObject("simulation", id, call(getSimulation, id));
+
+export const fetchAndStoreUser = (id) =>
+ fetchAndStoreObject("user", id, call(getUser, id));
+
+export const fetchAndStoreFailureModel = (id) =>
+ fetchAndStoreObject("failureModel", id, call(getFailureModel, id));
+
+export const fetchAndStoreCPU = (id) =>
+ fetchAndStoreObject("cpu", id, call(getCPU, id));
+
+export const fetchAndStoreGPU = (id) =>
+ fetchAndStoreObject("gpu", id, call(getGPU, id));
+
+export const fetchAndStoreMemory = (id) =>
+ fetchAndStoreObject("memory", id, call(getMemory, id));
+
+export const fetchAndStoreStorage = (id) =>
+ fetchAndStoreObject("storage", id, call(getStorage, id));
+
+export const fetchAndStoreMachinesOfTile = (tileId) =>
+ fetchAndStoreObjects("machine", call(getMachinesOfRackByTile, tileId));
+
+export const fetchAndStoreRackOnTile = (id, tileId) =>
+ fetchAndStoreObject("rack", id, call(getRackByTile, tileId));
+
+export const fetchAndStoreCoolingItem = (id) =>
+ fetchAndStoreObject("coolingItem", id, call(getCoolingItem, id));
+
+export const fetchAndStorePSU = (id) =>
+ fetchAndStoreObject("psu", id, call(getPSU, id));
+
+export const fetchAndStoreTilesOfRoom = (roomId) =>
+ fetchAndStoreObjects("tile", call(getTilesOfRoom, roomId));
+
+export const fetchAndStoreRoomsOfDatacenter = (datacenterId) =>
+ fetchAndStoreObjects("room", call(getRoomsOfDatacenter, datacenterId));
+
+export const fetchAndStoreDatacenter = (id) =>
+ fetchAndStoreObject("datacenter", id, call(getDatacenter, id));
+
+export const fetchAndStoreSection = (id) =>
+ fetchAndStoreObject("section", id, call(getSection, id));
+
+export const fetchAndStoreSectionsOfPath = (pathId) =>
+ fetchAndStoreObjects("section", call(getSectionsOfPath, pathId));
+
+export const fetchAndStorePath = (id) =>
+ fetchAndStoreObject("path", id, call(getPath, id));
+
+export const fetchAndStorePathsOfSimulation = (simulationId) =>
+ fetchAndStoreObjects("path", call(getPathsOfSimulation, simulationId));
diff --git a/src/sagas/profile.js b/src/sagas/profile.js
new file mode 100644
index 00000000..6a72e7c2
--- /dev/null
+++ b/src/sagas/profile.js
@@ -0,0 +1,12 @@
+import {call, put} from "redux-saga/effects";
+import {deleteCurrentUserSucceeded} from "../actions/users";
+import {deleteUser} from "../api/routes/users";
+
+export function* onDeleteCurrentUser(action) {
+ try {
+ yield call(deleteUser, action.userId);
+ yield put(deleteCurrentUserSucceeded());
+ } catch (error) {
+ console.log(error);
+ }
+}
diff --git a/src/sagas/simulations.js b/src/sagas/simulations.js
new file mode 100644
index 00000000..b699002e
--- /dev/null
+++ b/src/sagas/simulations.js
@@ -0,0 +1,30 @@
+import {call, put} from "redux-saga/effects";
+import {addToStore} from "../actions/objects";
+import {addSimulationSucceeded, deleteSimulationSucceeded} from "../actions/simulations";
+import {addSimulation, deleteSimulation} from "../api/routes/simulations";
+
+export function* onSimulationAdd(action) {
+ try {
+ const simulation = yield call(addSimulation, {name: action.name});
+ yield put(addToStore("simulation", simulation));
+
+ const authorization = {
+ simulationId: simulation.id,
+ userId: action.userId,
+ authorizationLevel: "OWN"
+ };
+ yield put(addToStore("authorization", authorization));
+ yield put(addSimulationSucceeded([authorization.userId, authorization.simulationId]));
+ } catch (error) {
+ console.log(error);
+ }
+}
+
+export function* onSimulationDelete(action) {
+ try {
+ yield call(deleteSimulation, action.id);
+ yield put(deleteSimulationSucceeded(action.id));
+ } catch (error) {
+ console.log(error);
+ }
+}
diff --git a/src/sagas/topology.js b/src/sagas/topology.js
new file mode 100644
index 00000000..6d359534
--- /dev/null
+++ b/src/sagas/topology.js
@@ -0,0 +1,71 @@
+import {put} from "redux-saga/effects";
+import {addPropToStoreObject} from "../actions/objects";
+import {fetchLatestDatacenterSucceeded} from "../actions/topology";
+import {
+ fetchAndStoreCoolingItem,
+ fetchAndStoreDatacenter,
+ fetchAndStorePathsOfSimulation,
+ fetchAndStorePSU,
+ fetchAndStoreRackOnTile,
+ fetchAndStoreRoomsOfDatacenter,
+ fetchAndStoreSectionsOfPath,
+ fetchAndStoreTilesOfRoom
+} from "./objects";
+
+export function* onFetchLatestDatacenter(action) {
+ try {
+ const paths = yield fetchAndStorePathsOfSimulation(action.currentSimulationId);
+ const latestPath = paths[paths.length - 1];
+ const sections = yield fetchAndStoreSectionsOfPath(latestPath.id);
+ const latestSection = sections[sections.length - 1];
+ yield fetchDatacenter(latestSection.datacenterId);
+ yield put(fetchLatestDatacenterSucceeded(latestSection.datacenterId));
+ } catch (error) {
+ console.log(error);
+ }
+}
+
+export function* fetchDatacenter(datacenterId) {
+ try {
+ const datacenter = yield fetchAndStoreDatacenter(datacenterId);
+ datacenter.roomIds = (yield fetchAndStoreRoomsOfDatacenter(datacenterId)).map(room => room.id);
+
+ for (let index in datacenter.roomIds) {
+ yield fetchRoom(datacenter.roomIds[index]);
+ }
+ } catch (error) {
+ console.log(error);
+ }
+}
+
+function* fetchRoom(roomId) {
+ const tiles = yield fetchAndStoreTilesOfRoom(roomId);
+ yield put(addPropToStoreObject("room", roomId, {tileIds: tiles.map(tile => tile.id)}));
+
+ for (let index in tiles) {
+ yield fetchTile(tiles[index]);
+ }
+}
+
+function* fetchTile(tile) {
+ if (!tile.objectType) {
+ return;
+ }
+ console.log(tile);
+ switch (tile.objectType) {
+ case "RACK":
+ const rack = yield fetchAndStoreRackOnTile(tile.objectId, tile.id);
+ yield put(addPropToStoreObject("tile", tile.id, {rackId: rack.id}));
+ break;
+ case "COOLING_ITEM":
+ const coolingItem = yield fetchAndStoreCoolingItem(tile.objectId);
+ yield put(addPropToStoreObject("tile", tile.id, {coolingItemId: coolingItem.id}));
+ break;
+ case "PSU":
+ const psu = yield fetchAndStorePSU(tile.objectId);
+ yield put(addPropToStoreObject("tile", tile.id, {psuId: psu.id}));
+ break;
+ default:
+ console.warn("Unknown object type encountered while fetching tile objects");
+ }
+}
diff --git a/src/sagas/users.js b/src/sagas/users.js
new file mode 100644
index 00000000..5f9bffa1
--- /dev/null
+++ b/src/sagas/users.js
@@ -0,0 +1,46 @@
+import {call, put} from "redux-saga/effects";
+import {logInSucceeded} from "../actions/auth";
+import {addToStore} from "../actions/objects";
+import {fetchAuthorizationsOfCurrentUserSucceeded} from "../actions/users";
+import {performTokenSignIn} from "../api/routes/token-signin";
+import {addUser, getAuthorizationsByUser} from "../api/routes/users";
+import {saveAuthLocalStorage} from "../auth/index";
+import {fetchAndStoreSimulation, fetchAndStoreUser} from "./objects";
+
+export function* onFetchLoggedInUser(action) {
+ try {
+ const tokenResponse = yield call(performTokenSignIn, action.payload.authToken);
+ let userId = tokenResponse.userId;
+
+ if (tokenResponse.isNewUser) {
+ saveAuthLocalStorage({authToken: action.payload.authToken});
+ const newUser = yield call(addUser, action.payload);
+ userId = newUser.id;
+ }
+
+ yield put(logInSucceeded(Object.assign({userId}, action.payload)));
+ } catch (error) {
+ console.log(error);
+ }
+}
+
+export function* onFetchAuthorizationsOfCurrentUser(action) {
+ try {
+ const authorizations = yield call(getAuthorizationsByUser, action.userId);
+
+ for (const authorization of authorizations) {
+ yield put(addToStore("authorization", authorization));
+
+ yield fetchAndStoreSimulation(authorization.simulationId);
+ yield fetchAndStoreUser(authorization.userId);
+ }
+
+ const authorizationIds = authorizations.map(authorization => (
+ [authorization.userId, authorization.simulationId]
+ ));
+
+ yield put(fetchAuthorizationsOfCurrentUserSucceeded(authorizationIds));
+ } catch (error) {
+ console.log(error);
+ }
+}