geoserver-node-client 0.0.2 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@ jobs:
10
10
  run-tests-maintenance:
11
11
  runs-on: ubuntu-latest
12
12
  env:
13
- GEOSERVER_VERSION: 2.18.2
13
+ GEOSERVER_VERSION: 2.19.3
14
14
  steps:
15
15
  - uses: actions/checkout@v2
16
16
 
@@ -33,7 +33,7 @@ jobs:
33
33
  run-tests-stable:
34
34
  runs-on: ubuntu-latest
35
35
  env:
36
- GEOSERVER_VERSION: 2.19.0
36
+ GEOSERVER_VERSION: 2.20.1
37
37
  steps:
38
38
  - uses: actions/checkout@v2
39
39
 
package/DOCS_HOME.md CHANGED
@@ -8,8 +8,10 @@ Node.js / JavaScript Client for the [GeoServer REST API](https://docs.geoserver.
8
8
 
9
9
  Compatible with [GeoServer](https://geoserver.org)
10
10
 
11
- - v2.17.x
12
- - v2.18.x
11
+ - v2.20.x
12
+ - v2.19.x
13
+ - v2.18.x (no more maintained and officially deprecated)
14
+ - v2.17.x (no more maintained and officially deprecated)
13
15
 
14
16
  ### Who do I talk to? ###
15
17
 
package/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2021, meggsimum (Dipl.-Ing. (FH) Christian Mayer)
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # GeoServer Node Client
2
2
 
3
+ [![npm version](https://badge.fury.io/js/geoserver-node-client.svg)](https://www.npmjs.com/package/geoserver-node-client)
4
+ ![](https://github.com/meggsimum/geoserver-node-client/actions/workflows/ci-geoserver-node-client.yml/badge.svg)
5
+
3
6
  Node.js / JavaScript Client for the [GeoServer REST API](https://docs.geoserver.org/stable/en/user/rest/).
4
7
 
5
8
  **CAUTION: This is highly bleeding edge, heavily under development and therefore breaking changes can be made at every time!**
@@ -12,8 +15,9 @@ Detailed API-Docs can be found [here](https://meggsimum.github.io/geoserver-node
12
15
 
13
16
  Compatible with [GeoServer](https://geoserver.org)
14
17
 
18
+ - v2.20.x
15
19
  - v2.19.x
16
- - v2.18.x
20
+ - v2.18.x (no more maintained and officially deprecated)
17
21
  - v2.17.x (no more maintained and officially deprecated)
18
22
 
19
23
  ### Setup
@@ -39,15 +43,41 @@ First start a GeoServer, e.g. by using this Docker container:
39
43
  docker run \
40
44
  -p 8080:8080 \
41
45
  -v /path/to/geoserver_mnt:/opt/geoserver_data \
42
- meggsimum/geoserver:2.18.2
46
+ meggsimum/geoserver:2.20.1
43
47
  ```
44
48
 
45
49
  Then, in an other terminal, run:
46
50
 
47
51
  ```shell
48
- npm run test
52
+ # specify the GeoServer version and run the test suite
53
+ GEOSERVER_VERSION=2.20.1 npm run test
54
+ ```
55
+
56
+ ### Release
57
+
58
+ The release to GitHub and npm is done via [release-it](https://github.com/release-it/release-it). This is the workflow for releasing:
59
+
60
+ 1. Make sure a `GITHUB_TOKEN` is available as environment variable. See [here](https://github.com/release-it/release-it/blob/master/docs/github-releases.md) for more information.
61
+
62
+ ```shell
63
+ export GITHUB_TOKEN=ADD-YOUR-TOKEN-HERE
64
+ ```
65
+
66
+ 2. Make sure you are logged in to npm and ensure you have the rights to make a release.
67
+
68
+ ```shell
69
+ npm login
70
+ # then enter your credentials
71
+ ```
72
+
73
+ 3. Locally checkout the latest `master` branch that you would like to release, then run:
74
+
75
+ ```shell
76
+ npm run release
49
77
  ```
50
78
 
79
+ 4. Follow the questions in the commandline.
80
+
51
81
  ### Who do I talk to? ###
52
82
 
53
83
  * meggsimum (Christian Mayer) - info __at## meggsimum ~~dot** de
package/demo/index.js CHANGED
@@ -18,6 +18,23 @@ grc.getVersion().then(versionInfo => {
18
18
  console.log('GeoServer REST version info', prettyJson(versionInfo));
19
19
  });
20
20
 
21
+ // NAMESPACES
22
+
23
+ // const nsPrefix = 'example-namespace';
24
+ // const nsUri = 'http://www.example.com'
25
+ // grc.namespaces.create(nsPrefix, nsUri).then(retVal => {
26
+ // console.log('Created GeoServer NS', prettyJson(retVal));
27
+ // });
28
+ // grc.namespaces.getAll().then(gsNamespaces => {
29
+ // console.log('GeoServer All NS', prettyJson(gsNamespaces));
30
+ // });
31
+ // grc.namespaces.get(nsPrefix).then(gsNamespaces => {
32
+ // console.log('GeoServer NS', prettyJson(gsNamespaces));
33
+ // });
34
+ // grc.namespaces.delete(nsPrefix).then(gsNamespaces => {
35
+ // console.log('Deleted GeoServer NS', prettyJson(gsNamespaces));
36
+ // });
37
+
21
38
  // WORKSPACES
22
39
 
23
40
  // grc.workspaces.getAll().then(gsWorkspaces => {
@@ -70,9 +87,9 @@ grc.getVersion().then(versionInfo => {
70
87
  // grc.datastores.createWmsStore(ws, 'testWmsDs', wmsUrl).then(retVal => {
71
88
  // console.log('Created WMS data store', prettyJson(retVal));
72
89
  // });
73
- // const wfsCapsUrl = 'https://ows.terrestris.de/geoserver/osm/wfs?service=wfs&version=1.1.0&request=GetCapabilities';
90
+ // const wfsCapsUrl = 'https://services.meggsimum.de/geoserver/ows?service=wfs&version=1.1.0&request=GetCapabilities';
74
91
  // const namespaceUrl = 'http://test';
75
- // grc.datastores.createWfsStore(ws, 'testWfsDs', wfsCapsUrl, namespaceUrl).then(retVal => {
92
+ // grc.datastores.createWfsStore(ws, 'testWfsDs', wfsCapsUrl, namespaceUrl, false).then(retVal => {
76
93
  // console.log('Created WFS data store', prettyJson(retVal));
77
94
  // });
78
95
  // grc.datastores.deleteDataStore(ws, 'testWfsDs', false).then(gsWmsStores => {
@@ -6,6 +6,7 @@ import DatastoreClient from './src/datastore.js';
6
6
  import ImageMosaicClient from './src/imagemosaic.js';
7
7
  import SecurityClient from './src/security.js';
8
8
  import SettingsClient from './src/settings.js';
9
+ import NamespaceClient from './src/namespace.js';
9
10
 
10
11
  /**
11
12
  * Client for GeoServer REST API.
@@ -33,6 +34,8 @@ export default class GeoServerRestClient {
33
34
  this.styles = new StyleClient(this.url, this.user, this.password);
34
35
  /** @member {WorkspaceClient} workspaces GeoServer REST client instance for workspaces */
35
36
  this.workspaces = new WorkspaceClient(this.url, this.user, this.password);
37
+ /** @member {NamespaceClient} namespaces GeoServer REST client instance for namespaces */
38
+ this.namespaces = new NamespaceClient(this.url, this.user, this.password);
36
39
  /** @member {DatastoreClient} datastores GeoServer REST client instance for data stores */
37
40
  this.datastores = new DatastoreClient(this.url, this.user, this.password);
38
41
  /** @member {ImageMosaicClient} imagemosaics GeoServer REST client instance for image mosaics */
@@ -45,7 +48,7 @@ export default class GeoServerRestClient {
45
48
 
46
49
  /**
47
50
  * Get the GeoServer version.
48
- *
51
+ *
49
52
  * @returns {String|Boolean} The version of GeoServer or 'false'
50
53
  */
51
54
  async getVersion () {
@@ -67,7 +70,7 @@ export default class GeoServerRestClient {
67
70
 
68
71
  /**
69
72
  * Checks if the configured GeoServer REST connection exists.
70
- *
73
+ *
71
74
  * @returns {Boolean} If the connection exists
72
75
  */
73
76
  async exists () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geoserver-node-client",
3
- "version": "0.0.2",
3
+ "version": "0.0.6",
4
4
  "description": "Node.js client for GeoServer REST API",
5
5
  "type": "module",
6
6
  "main": "geoserver-rest-client.js",
@@ -20,18 +20,18 @@
20
20
  "author": "C. Mayer, meggsimum (info_at*meggsimum?dot?de)",
21
21
  "license": "BSD-2-Clause",
22
22
  "dependencies": {
23
- "node-fetch": "^2.6.1"
23
+ "node-fetch": "^2.6.5"
24
24
  },
25
25
  "devDependencies": {
26
- "chai": "^4.3.0",
27
- "eslint": "^7.21.0",
26
+ "chai": "^4.3.4",
27
+ "eslint": "^7.32.0",
28
28
  "eslint-config-standard": "^14.1.1",
29
- "eslint-plugin-import": "^2.22.1",
29
+ "eslint-plugin-import": "^2.25.2",
30
30
  "eslint-plugin-node": "^11.1.0",
31
31
  "eslint-plugin-promise": "^4.3.1",
32
32
  "eslint-plugin-standard": "^4.1.0",
33
- "jsdoc": "^3.6.6",
34
- "mocha": "^8.3.0",
35
- "release-it": "^14.10.0"
33
+ "jsdoc": "^3.6.7",
34
+ "mocha": "^9.1.3",
35
+ "release-it": "^14.11.6"
36
36
  }
37
37
  }
package/src/datastore.js CHANGED
@@ -228,6 +228,7 @@ s */
228
228
  * Creates a PostGIS based data store.
229
229
  *
230
230
  * @param {String} workspace The WS to create the data store in
231
+ * @param {String} namespaceUri The namespace URI of the workspace
231
232
  * @param {String} dataStore The data store name to be created
232
233
  * @param {String} pgHost The PostGIS DB host
233
234
  * @param {String} pgPort The PostGIS DB port
@@ -239,12 +240,15 @@ s */
239
240
  *
240
241
  * @returns {Boolean} If the store could be created
241
242
  */
242
- async createPostgisStore (workspace, dataStore, pgHost, pgPort, pgUser, pgPassword, pgSchema, pgDb, exposePk) {
243
+ async createPostgisStore (workspace, namespaceUri, dataStore, pgHost, pgPort, pgUser, pgPassword, pgSchema, pgDb, exposePk) {
243
244
  const body = {
244
245
  dataStore: {
245
246
  name: dataStore,
246
247
  type: 'PostGIS',
247
248
  enabled: true,
249
+ workspace: {
250
+ name: workspace
251
+ },
248
252
  connectionParameters: {
249
253
  entry: [
250
254
  {
@@ -273,7 +277,7 @@ s */
273
277
  },
274
278
  {
275
279
  '@key': 'namespace',
276
- $: workspace
280
+ $: namespaceUri
277
281
  },
278
282
  {
279
283
  '@key': 'user',
@@ -397,10 +401,11 @@ s */
397
401
  * @param {String} dataStore The data store name
398
402
  * @param {String} wfsCapabilitiesUrl WFS capabilities URL
399
403
  * @param {String} namespaceUrl URL of the GeoServer namespace
404
+ * @param {Boolean} [useHttpConnectionPooling=true] use HTTP connection pooling for WFS connection
400
405
  *
401
406
  * @returns {Boolean} If store could be created
402
407
  */
403
- async createWfsStore (workspace, dataStore, wfsCapabilitiesUrl, namespaceUrl) {
408
+ async createWfsStore (workspace, dataStore, wfsCapabilitiesUrl, namespaceUrl, useHttpConnectionPooling) {
404
409
  const body = {
405
410
  dataStore: {
406
411
  name: dataStore,
@@ -414,6 +419,10 @@ s */
414
419
  {
415
420
  '@key': 'namespace',
416
421
  $: namespaceUrl
422
+ },
423
+ {
424
+ '@key': 'WFSDataStoreFactory:USE_HTTP_CONNECTION_POOLING',
425
+ $: useHttpConnectionPooling !== false ? 'true' : 'false'
417
426
  }
418
427
  ]
419
428
  }
package/src/layer.js CHANGED
@@ -369,10 +369,11 @@ export default class LayerClient {
369
369
  * @param {String} defaultValue The default time value, e.g. 'MINIMUM' or 'MAXIMUM' or 'NEAREST' or 'FIXED'
370
370
  * @param {Boolean} [nearestMatchEnabled] Enable nearest match
371
371
  * @param {Boolean} [rawNearestMatchEnabled] Enable raw nearest match
372
+ * @param {String} [acceptableInterval] Acceptable interval for nearest match, e.g.'PT30M'
372
373
  *
373
374
  * @returns If time dimension could be enabled
374
375
  */
375
- async enableTimeCoverage (workspace, dataStore, name, presentation, resolution, defaultValue, nearestMatchEnabled, rawNearestMatchEnabled) {
376
+ async enableTimeCoverage (workspace, dataStore, name, presentation, resolution, defaultValue, nearestMatchEnabled, rawNearestMatchEnabled, acceptableInterval) {
376
377
  try {
377
378
  const body = {
378
379
  coverage: {
@@ -389,7 +390,8 @@ export default class LayerClient {
389
390
  strategy: defaultValue
390
391
  },
391
392
  nearestMatchEnabled: nearestMatchEnabled,
392
- rawNearestMatchEnabled: rawNearestMatchEnabled
393
+ rawNearestMatchEnabled: rawNearestMatchEnabled,
394
+ acceptableInterval: acceptableInterval
393
395
  }
394
396
  }
395
397
  ]
@@ -0,0 +1,142 @@
1
+ import fetch from 'node-fetch';
2
+
3
+ /**
4
+ * Client for GeoServer namespace
5
+ *
6
+ * @module NamespaceClient
7
+ */
8
+ export default class NamespaceClient {
9
+ /**
10
+ * Creates a GeoServer REST NamespaceClient instance.
11
+ *
12
+ * @param {String} url The URL of the GeoServer REST API endpoint
13
+ * @param {String} user The user for the GeoServer REST API
14
+ * @param {String} password The password for the GeoServer REST API
15
+ */
16
+ constructor (url, user, password) {
17
+ this.url = url.endsWith('/') ? url : url + '/';
18
+ this.user = user;
19
+ this.password = password;
20
+ }
21
+
22
+ /**
23
+ * Returns all namespaces.
24
+ *
25
+ * @returns {Object|Boolean} An object describing the namespace or 'false'
26
+ */
27
+ async getAll () {
28
+ try {
29
+ const auth =
30
+ Buffer.from(this.user + ':' + this.password).toString('base64');
31
+ const response = await fetch(this.url + 'namespaces.json', {
32
+ credentials: 'include',
33
+ method: 'GET',
34
+ headers: {
35
+ Authorization: 'Basic ' + auth
36
+ }
37
+ });
38
+ const json = await response.json();
39
+ return json;
40
+ } catch (error) {
41
+ return false;
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Creates a new namespace.
47
+ *
48
+ * @param {String} prefix Prefix of the new namespace
49
+ * @param {String} uri Uri of the new namespace
50
+ *
51
+ * @returns {String|Boolean} The name of the created namespace or 'false'
52
+ */
53
+ async create (prefix, uri) {
54
+ try {
55
+ const body = {
56
+ namespace: {
57
+ prefix: prefix,
58
+ uri: uri
59
+ }
60
+ };
61
+
62
+ const auth =
63
+ Buffer.from(this.user + ':' + this.password).toString('base64');
64
+
65
+ const response = await fetch(this.url + 'namespaces', {
66
+ credentials: 'include',
67
+ method: 'POST',
68
+ headers: {
69
+ Authorization: 'Basic ' + auth,
70
+ 'Content-Type': 'application/json'
71
+ },
72
+ body: JSON.stringify(body)
73
+ });
74
+
75
+ if (response.status === 201) {
76
+ const responseText = await response.text();
77
+ return responseText;
78
+ } else {
79
+ return false;
80
+ }
81
+ } catch (error) {
82
+ return false;
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Returns a namespace.
88
+ *
89
+ * @param {String} name Name of the namespace
90
+ * @returns {Object|Boolean} An object describing the namespace or 'false'
91
+ */
92
+ async get (name) {
93
+ try {
94
+ const auth =
95
+ Buffer.from(this.user + ':' + this.password).toString('base64');
96
+ const response = await fetch(this.url + 'namespaces/' + name + '.json', {
97
+ credentials: 'include',
98
+ method: 'GET',
99
+ headers: {
100
+ Authorization: 'Basic ' + auth
101
+ }
102
+ });
103
+ if (response.status === 200) {
104
+ return await response.json();
105
+ } else {
106
+ return false;
107
+ }
108
+ } catch (error) {
109
+ return false;
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Deletes a namespace.
115
+ *
116
+ * @param {String} name Name of the namespace to delete
117
+ *
118
+ * @returns {Boolean} If deletion was successful
119
+ */
120
+ async delete (name) {
121
+ try {
122
+ const auth =
123
+ Buffer.from(this.user + ':' + this.password).toString('base64');
124
+ const response = await fetch(this.url + 'namespaces/' + name, {
125
+ credentials: 'include',
126
+ method: 'DELETE',
127
+ headers: {
128
+ Authorization: 'Basic ' + auth
129
+ }
130
+ });
131
+
132
+ // TODO map other HTTP status
133
+ if (response.status === 200) {
134
+ return true;
135
+ } else {
136
+ return false;
137
+ }
138
+ } catch (error) {
139
+ return false;
140
+ }
141
+ }
142
+ }
package/test/test.js CHANGED
@@ -9,6 +9,10 @@ const pw = 'geoserver';
9
9
  const grc = new GeoServerRestClient(url, user, pw);
10
10
 
11
11
  const workSpace = 'my-workspace';
12
+
13
+ const nameSpace = 'my-namespace';
14
+ const nameSpaceUri = 'http://www.example.com';
15
+
12
16
  const geoServerVersion = process.env.GEOSERVER_VERSION;
13
17
 
14
18
  describe('Basic GeoServer', () => {
@@ -126,6 +130,40 @@ describe('Workspace', () => {
126
130
  });
127
131
  });
128
132
 
133
+ describe('Namespace', () => {
134
+ it('has no namespaces', async () => {
135
+ const gsNamespaces = await grc.namespaces.getAll();
136
+ expect(gsNamespaces.namespaces).to.equal('');
137
+ });
138
+
139
+ it('creates one namespace', async () => {
140
+ const result = await grc.namespaces.create(nameSpace, nameSpaceUri);
141
+ expect(result).to.equal(nameSpace);
142
+ });
143
+
144
+ it('has one namespace', async () => {
145
+ const gsNameSpaces = await grc.namespaces.getAll();
146
+ expect(gsNameSpaces.namespaces.namespace.length).to.equal(1);
147
+ expect(gsNameSpaces.namespaces.namespace[0].name).to.equal(nameSpace);
148
+ });
149
+
150
+ it('query dedicated namespace', async () => {
151
+ const gsNameSpace = await grc.namespaces.get(nameSpace);
152
+ expect(gsNameSpace.namespace.prefix).to.equal(nameSpace);
153
+ expect(gsNameSpace.namespace.uri).to.equal(nameSpaceUri);
154
+ });
155
+
156
+ it('delete namespace', async () => {
157
+ const result = await grc.namespaces.delete(nameSpace);
158
+ expect(result).to.be.true;
159
+ });
160
+
161
+ it('has no namespace', async () => {
162
+ const gsNameSpaces = await grc.namespaces.getAll();
163
+ expect(gsNameSpaces.namespaces).to.equal('');
164
+ });
165
+ });
166
+
129
167
  describe('Datastore', () => {
130
168
  let createdWorkSpace;
131
169
 
package/demo/dev.js DELETED
@@ -1,275 +0,0 @@
1
- import GeoServerRestClient from '../geoserver-rest-client.js';
2
- import fs from 'fs';
3
- import { execSync } from 'child_process'
4
-
5
- const geoserverUrl = 'http://localhost:8080/geoserver/rest/';
6
- const geoserverDefaultUser = 'mgsm-admin';
7
- const geoserverDefaultPw = 'VB?w10&0A2s8PU?BPM&Nn!8kl';
8
- const role = 'ADMIN';
9
-
10
- // TODO: read from secrets
11
- const newGeoserverUser = 'mgsm-admin';
12
- const newGeoserverPw = 'VB?w10&0A2s8PU?BPM&Nn!8kl';
13
-
14
- const workspaceWorld = 'mgsm-world';
15
- const workspaceGermany = 'mgsm-ger';
16
-
17
- const gsDataDir = '/opt/geoserver_data/';
18
- const countriesGpkgUrl = 'https://github.com/JakobMiksch/geodata/raw/main/vector-data.gpkg?raw=true';
19
- const worldRasterUrl = 'https://github.com/JakobMiksch/geodata/raw/main/world.tiff';
20
- const neGpkgPath = gsDataDir + 'natural_earth_vector.gpkg';
21
- const neWorldRasterPath = gsDataDir + 'world.tif';
22
- const worldRasterDs = 'world-raster';
23
- const worldRasterLayer = 'ne_world';
24
- const worldRasterTitle = 'World Image';
25
-
26
- const postalCodesUrl = 'https://github.com/JakobMiksch/geodata/raw/main/postal_codes_germany.gpkg';
27
- const postalCodesPath = gsDataDir + 'postal_codes.gpkg';
28
-
29
- /**
30
- * Main function
31
- */
32
- async function initGeoserver () {
33
- console.log('accessing geoserver');
34
- const workspaceGermany = 'mgsm-ger';
35
- const gpkgStore = 'postal-code-store';
36
- const nativeLayerName = undefined;
37
- const layerName = 'postal_codes_germany';
38
- const layerTitle = 'Postal Codes Germany';
39
-
40
- const layerCreated = await grc.layers.publishFeatureType(
41
- workspaceGermany, gpkgStore, nativeLayerName, layerName, layerTitle,
42
- 'EPSG:4326', true, 'asdfasdfasdfasdf asdfasdfsadf asdfasdf afas asdf asdfas asdf asdfas asdf asdfas asfd asdfas as dfas dfasdf asdf asdfas asdfa sdfawesdf'
43
- );
44
-
45
- console.log(layerCreated);
46
-
47
- // let result;
48
- // result = await grc.layers.get('mgsm-ger:postal_codes_germany');
49
- // console.log(result);
50
-
51
- // result = await grc.layers.modifyAttribution('mgsm-ger:postal_codes_germany', 'Apfelbaum', 'www.zeit.de');
52
- // console.log(result);
53
-
54
- // result = await grc.layers.get('mgsm-ger:postal_codes_germany');
55
- // console.log(result);
56
-
57
- // await addContactInformation();
58
-
59
- // await adaptSecurity();
60
-
61
- // await createWorkspaces();
62
-
63
- // await publishGlobalVectorData();
64
-
65
- // await publishWorldRaster();
66
-
67
- // await publishPostalCodes();
68
- }
69
-
70
- /**
71
- * Adapts security settings for GeoServer
72
- */
73
- async function adaptSecurity () {
74
- const user = newGeoserverUser;
75
- const userPw = newGeoserverPw;
76
-
77
- if (!user || !userPw || user === '' || userPw === '') {
78
- console.error('No valid user or user password given - EXIT.');
79
- }
80
-
81
- const userCreated = await grc.security.createUser(user, userPw);
82
- if (userCreated) {
83
- console.info('Successfully created user', user);
84
- }
85
-
86
- const roleAssigend = await grc.security.associateUserRole(user, role);
87
- if (roleAssigend) {
88
- console.info(`Successfully added role ${role} to user ${user}`);
89
- }
90
-
91
- // disable user
92
- const adminDisabled = await grc.security.updateUser(geoserverDefaultUser, geoserverDefaultPw, false);
93
- if (adminDisabled) {
94
- console.info('Successfully disabled default "admin" user');
95
- }
96
- }
97
-
98
- /**
99
- * Adds basic contact information
100
- */
101
- async function addContactInformation () {
102
- const address = 'Schillerstraße 2a';
103
- const city = 'Mutterstadt';
104
- const country = 'Deutschland';
105
- const state = undefined;
106
- const postalCode = '67112';
107
- const email = 'info@meggsimum.de';
108
- const organization = 'meggsimum – Büro für Geoinformatik';
109
- const contactPerson = 'Christian Mayer';
110
- const phoneNumber = undefined;
111
-
112
- const result = await grc.settings.updateContactInformation(address, city, country, postalCode, state, email, organization, contactPerson, phoneNumber);
113
- if (result) {
114
- console.log('Changed contact information.');
115
- }
116
- }
117
-
118
- /**
119
- * Creates the basic workspaces
120
- */
121
- async function createWorkspaces () {
122
- const wsWorldCreated = await grc.workspaces.create(workspaceWorld);
123
- console.log('Created Workspace World', wsWorldCreated);
124
-
125
- const wsGermanyCreated = await grc.workspaces.create(workspaceGermany);
126
- console.log('Created Workspace Germany', wsGermanyCreated);
127
- }
128
-
129
- /**
130
- * Publish postal codes from Germany
131
- */
132
- async function publishPostalCodes () {
133
- const gpkgStore = 'postal-code-store';
134
- const nativeLayerName = undefined;
135
- const layerName = 'postal_codes_germany';
136
- const layerTitle = 'Postal Codes Germany';
137
-
138
- const wsExists =
139
- await grc.datastores.getDataStore(workspaceGermany, gpkgStore);
140
- const lyrExists =
141
- await grc.layers.get(`${workspaceGermany}:${layerName}`);
142
-
143
- if (wsExists && lyrExists) {
144
- console.info('Datastore and layer for postal codes already exist - SKIP!');
145
- return;
146
- }
147
-
148
- // TODO replace by native node call
149
- execSync(`wget -N -O ${postalCodesPath} ${postalCodesUrl}`);
150
-
151
- const postalStoreCreated = await grc.datastores.createGpkgStore(
152
- workspaceGermany, gpkgStore, postalCodesPath
153
- );
154
-
155
- console.log('Successfully created postal code GPKG store', postalStoreCreated);
156
-
157
- const layerCreated = await grc.layers.publishFeatureType(
158
- workspaceGermany, gpkgStore, nativeLayerName, layerName, layerTitle,
159
- 'EPSG:4326', true
160
- );
161
-
162
- if (layerCreated) {
163
- console.log(`Created vector layer for postal codes "${layerName}"`);
164
- }
165
- }
166
-
167
- /**
168
- * Publishes the world vector data (currently countries, rivers, places)
169
- */
170
- async function publishGlobalVectorData () {
171
- const gpkgStore = 'natural-earth-gpkg-store';
172
- const countriesLyr = 'ne_10m_admin_0_countries';
173
- const riversLyr = 'ne_10m_rivers_lake_centerlines';
174
- const placesLyr = 'ne_10m_populated_places';
175
-
176
- const wsExists =
177
- await grc.datastores.getDataStore(workspaceWorld, gpkgStore);
178
- const lyr1Exists =
179
- await grc.layers.get(`${workspaceWorld}:${countriesLyr}`);
180
- const lyr2Exists =
181
- await grc.layers.get(`${workspaceWorld}:${riversLyr}`);
182
- const lyr3Exists =
183
- await grc.layers.get(`${workspaceWorld}:${placesLyr}`);
184
-
185
- if (wsExists && lyr1Exists && lyr2Exists && lyr3Exists) {
186
- console.info('Datastore and layers for global vector data already exist - SKIP!');
187
- return;
188
- }
189
-
190
- // TODO replace by native node call
191
- execSync(`wget -N -O ${neGpkgPath} ${countriesGpkgUrl}`);
192
-
193
- // NOTE: here the relative path within the GeoServer is required
194
- const neStoreCreated = await grc.datastores.createGpkgStore(
195
- workspaceWorld, gpkgStore, neGpkgPath
196
- );
197
-
198
- console.log('Successfully created NE GPKG store', neStoreCreated);
199
-
200
- // publish vector layers
201
- publishVectorLayerWithStyle(gpkgStore, countriesLyr, 'World Countries', 'countries');
202
- publishVectorLayerWithStyle(gpkgStore, riversLyr, 'World Rivers', 'rivers');
203
- publishVectorLayerWithStyle(gpkgStore, placesLyr, 'World Places', 'places');
204
- }
205
-
206
- /**
207
- * Util for publishing a layer with a style
208
- */
209
- async function publishVectorLayerWithStyle (store, layerName, layerTitle, styleName) {
210
- const nativeLayerName = undefined;
211
-
212
- const layerCreated = await grc.layers.publishFeatureType(
213
- workspaceWorld, store, nativeLayerName, layerName, layerTitle,
214
- 'EPSG:4326', true
215
- );
216
-
217
- if (layerCreated) {
218
- console.log(`Created vector layer "${layerName}"`);
219
- }
220
-
221
- try {
222
- const sldFilePath = styleName + '.sld';
223
- const sldBody = fs.readFileSync(sldFilePath, 'utf8');
224
-
225
- // publish style
226
- const stylePublished = await grc.styles.publish(workspaceWorld, styleName, sldBody);
227
-
228
- console.log('Published style: ', stylePublished);
229
-
230
- const qualifiedName = `${workspaceWorld}:${layerName}`;
231
- const styleAssigend = await grc.styles.assignStyleToLayer(qualifiedName, styleName,
232
- workspaceWorld, true
233
- );
234
-
235
- console.log(`Style "${styleName}" assigned to layer "${qualifiedName}"`, styleAssigend);
236
- } catch (e) {
237
- console.error('Error:', e.stack);
238
- }
239
- }
240
-
241
- /**
242
- * Publishes the NE GeoTiff based World Raster
243
- */
244
- async function publishWorldRaster () {
245
- const wsExists =
246
- await grc.datastores.getCoverageStore(workspaceWorld, worldRasterDs);
247
- const lyrExists = await grc.layers.get(`${workspaceWorld}:${worldRasterLayer}`);
248
-
249
- if (wsExists && lyrExists) {
250
- console.info('Datastore and layer for world raster data already exist - SKIP!');
251
- return;
252
- }
253
-
254
- // TODO replace by native node call
255
- execSync(`wget -N -O ${neWorldRasterPath} ${worldRasterUrl}`);
256
-
257
- console.log('Downloaded GeoTIFF file');
258
-
259
- const geotiffCreated = await grc.datastores.createGeotiffFromFile(
260
- workspaceWorld, worldRasterDs, worldRasterLayer,
261
- worldRasterTitle, neWorldRasterPath
262
- );
263
-
264
- console.log('Created GeoTIFF world raster layer', geotiffCreated);
265
- }
266
-
267
- // check if we can connect to GeoServer REST API
268
- const grc = new GeoServerRestClient(geoserverUrl, geoserverDefaultUser, geoserverDefaultPw);
269
- grc.exists().then(gsExists => {
270
- if (gsExists === true) {
271
- initGeoserver();
272
- } else {
273
- console.error('Could not connect to GeoServer REST API - ABORT!');
274
- }
275
- });