-
Notifications
You must be signed in to change notification settings - Fork 383
/
ObservableUtils.js
103 lines (97 loc) · 4.8 KB
/
ObservableUtils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
const Rx = require('rxjs');
const {get} = require('lodash');
const {parseString} = require('xml2js');
const {stripPrefix} = require('xml2js/lib/processors');
const GeoStoreApi = require('../api/GeoStoreDAO');
const {updatePermissions, updateAttribute, doNothing} = require('../actions/maps');
const ConfigUtils = require('../utils/ConfigUtils');
const {basicSuccess, basicError} = require('../utils/NotificationUtils');
class OGCError extends Error {
constructor(message, code) {
super(message);
this.name = 'OGCError';
this.code = code;
}
}
const parseXML = (xml, options = {
tagNameProcessors: [stripPrefix],
explicitArray: false,
mergeAttrs: true
} ) => Rx.Observable.bindNodeCallback((data, callback) => parseString(data, options, callback))(xml);
/**
* Intercept OGC Exception (200 response with exceptionReport) to throw error in the stream
* @param {observable} observable The observable that emits the server response
* @return {observable} The observable that returns the response or throws the error.
*/
const interceptOGCError = (observable) => observable.switchMap(response => {
if (typeof response.data === "string") {
if (response.data.indexOf("ExceptionReport") > 0) {
return Rx.Observable.bindNodeCallback( (data, callback) => parseString(data, {
tagNameProcessors: [stripPrefix],
explicitArray: false,
mergeAttrs: true
}, callback))(response.data).map(data => {
const message = get(data, "ExceptionReport.Exception.ExceptionText");
throw new OGCError(message || "Undefined OGC Service Error", get(data, "ExceptionReport.Exception.exceptionCode"));
});
}
}
return Rx.Observable.of(response);
});
const createAssociatedResource = ({attribute, permissions, mapId, metadata, value, category, type, optionsRes, optionsAttr} = {}) => {
return Rx.Observable.fromPromise(
GeoStoreApi.createResource(metadata, value, category, optionsRes)
.then(res => res.data))
.switchMap((resourceId) => {
// update permissions
let actions = [];
actions.push(updatePermissions(resourceId, permissions));
const attibuteUri = ConfigUtils.getDefaults().geoStoreUrl + "data/" + resourceId + "/raw?decode=datauri";
const encodedResourceUri = encodeURIComponent(encodeURIComponent(attibuteUri));
// UPDATE resource map with new attribute
actions.push(updateAttribute(mapId, attribute, encodedResourceUri, type, optionsAttr));
// display a success message
actions.push(basicSuccess({message: "maps.feedback." + attribute + ".savedSuccesfully" }));
return Rx.Observable.from(actions);
})
.catch(() => Rx.Observable.of(basicError({message: "maps.feedback.errorWhenSaving"})));
};
const updateAssociatedResource = ({permissions, resourceId, value, attribute, options} = {}) => {
return Rx.Observable.fromPromise(GeoStoreApi.putResource(resourceId, value, options)
.then(res => res.data))
.switchMap((id) => {
let actions = [];
actions.push(basicSuccess({ message: "maps.feedback." + attribute + ".updatedSuccesfully"}));
actions.push(updatePermissions(id, permissions));
return Rx.Observable.from(actions);
})
.catch(() => Rx.Observable.of(basicError({message: "maps.feedback.errorWhenUpdating"})));
};
const deleteAssociatedResource = ({mapId, attribute, type, resourceId, options} = {}) => {
return Rx.Observable.fromPromise(GeoStoreApi.deleteResource(resourceId, options)
.then(res => res.status === 204))
.switchMap((deleted) => {
let actions = [];
if (deleted) {
actions.push(basicSuccess({ message: "maps.feedback." + attribute + ".deletedSuccesfully" }));
actions.push(updateAttribute(mapId, attribute, "NODATA", type, options));
return Rx.Observable.from(actions);
}
actions.push(doNothing());
return Rx.Observable.from(actions);
})
.catch(() => Rx.Observable.of(basicError({message: "maps.feedback.errorWhenDeleting"})));
};
const deleteResourceById = (resId, options) => resId ?
GeoStoreApi.deleteResource(resId, options)
.then((res) => {return {data: res.data, resType: "success", error: null}; })
.catch((e) => {return {error: e, resType: "error"}; }) :
Rx.Observable.of({resType: "success"});
module.exports = {
parseXML,
deleteResourceById,
createAssociatedResource,
updateAssociatedResource,
deleteAssociatedResource,
interceptOGCError
};