Skip to content

Commit 54d5df1

Browse files
authored
Merge pull request #498 from modelix/chore/docs/model-server-run
docs(model-server): properly document how to start a model-server
2 parents 4b1b60d + a809a67 commit 54d5df1

File tree

7 files changed

+331
-10
lines changed

7 files changed

+331
-10
lines changed
48.9 KB
Loading
73.2 KB
Loading
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
= How-To Run the Light `model-server` in MPS as a Plugin
2+
:navtitle: mps-model-server-plugin
3+
4+
5+
You can run a *light version* of the `model-server` directly in MPS via the dedicated *MPS as Modelix Model Server Plugin*, which is published over at the https://plugins.jetbrains.com/plugin/22834-mps-as-modelix-model-server[JetBrains Marketplace^].
6+
7+
NOTE: More information on the component in general can be found in the xref:core:reference/component-mps-model-server-plugin.adoc[corresponding component reference].
8+
9+
[IMPORTANT]
10+
====
11+
A light model-server does not provide the full features as an independent `model-server` instance will.
12+
More *advanced features* will not work with this light version (e.g., modelix specific repositories/branches, or the xref:howto/metrics.adoc[metrics]).
13+
14+
If you want the full capabilities of the `model-server`, check out xref:howto/usage-model-api-gen-gradle.adoc[how to start it standalone].
15+
====
16+
17+
18+
== How to Install the Plugin
19+
20+
In MPS navigate to menu:File[Settings > Plugins (left) > Marketplace (top)].
21+
Search for "modelix model server" and press btn:[Install] and afterwards btn:[Restart IDE].
22+
23+
image::model-server-plugin-marketplace.png[Installing the MPS model-server plugin]
24+
25+
You can access the light `model-server` via the
26+
xref:reference/component-light-model-client.adoc[light-model-client].
27+
28+
29+
== How to Run the Plugin
30+
31+
Once you restart MPS, the light `model-server` will start automatically with MPS.
32+
There are no graphical user interfaces, but to verify you can check the MPS log for
33+
34+
[source,bash]
35+
--
36+
starting modelix server
37+
--
38+
39+
The `model-server` will run by default on port `48305`.
40+
You can check the health status over at http://127.0.0.1:48305/health[^].
41+
42+
If you want to find out how connect a client and send queries to the plugin, have a look at the xref:howto/modelql.adoc[ModelQL documentation] or the xref:core:reference/component-mps-model-server-plugin.adoc[component reference].
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
= How-To use the `model-client` v2 (Kotlin)
2+
:navtitle: Use the `model-client` v2 (Kotlin)
3+
4+
NOTE: In order to use the client, you will need a xref:core:howto/usage-model-server.adoc[running model-server] to connect to.
5+
6+
== Gradle Dependency
7+
8+
To use the `model-client` v2 you have to add the `model-client` library to your dependencies.
9+
Add the following to your `build.gradle.kts`:
10+
11+
[source,kotlin]
12+
--
13+
repositories {
14+
mavenLocal {}
15+
maven { url = uri("https://artifacts.itemis.cloud/repository/maven-mps/") }
16+
// ...
17+
}
18+
// ...
19+
dependencies {
20+
implementation("org.modelix:model-client:4.6.0")
21+
// ...
22+
}
23+
--
24+
25+
26+
== Usage
27+
28+
Once set up, creating an instance that loads the entire model from the server can be done like this:
29+
30+
31+
[source, kotlin]
32+
--
33+
val client = ModelClientV2.builder()
34+
.url("http://localhost:28101/v2")
35+
.build()
36+
--
37+
38+
Nearly all operations are interfacing with a remote repository, consequently most operations in the client are https://kotlinlang.org/docs/composing-suspending-functions.html[suspending functions^].
39+
As a result, we need to use https://kotlinlang.org/docs/coroutines-basics.html[Kotlin Coroutines^] to execute these functions.
40+
To initialize the client, we can call (we assume coroutine execution in all following code blocks):
41+
42+
[source, kotlin]
43+
--
44+
// init is a suspend fun, so we use a coroutine
45+
runBlocking(CoroutineScope(Dispatchers.Default).coroutineContext){
46+
client.init()
47+
}
48+
49+
--
50+
51+
Afterward, we create a repository and replicate it locally into a `ReplicatedModel`.
52+
This data structure automatically synchronizes its content with the remote.
53+
We can consequently assume that its data is always correct and up-to-date.
54+
55+
[source, kotlin]
56+
--
57+
// create a new repository
58+
val myRepoId: RepositoryId = RepositoryId("myRepository")
59+
client.initRepository(myRepoId)
60+
61+
// obtain the main branch created by default
62+
val myBranchReference: BranchReference = BranchReference(repositoryId = myRepoId, branchName = RepositoryId.DEFAULT_BRANCH)
63+
64+
// replicate the branch content
65+
val replicatedModel: ReplicatedModel = client.getReplicatedModel(myBranchReference)
66+
// start the continuous replication
67+
replicatedModel.start()
68+
--
69+
70+
To ensure that read and write are executed correctly, we need to use read and write transactions whenever we interact with the content, e.g. by adding a new child:
71+
72+
[source, kotlin]
73+
--
74+
// initial root node after repository initialization has the id 1
75+
val rootNode: INode = replicatedModel.getBranch().getRootNode()
76+
77+
// to create a node we need run a write transaction
78+
replicatedModel.getBranch().runWrite {
79+
val newChild: INode = rootNode.addNewChild("myRole")
80+
println("Added node $newChild under parent ${newChild.parent}")
81+
}
82+
83+
// to get model content we need a read transaction
84+
replicatedModel.getBranch().runRead {
85+
println("All nodes in repository: ${(rootNode.getDescendants(true).toMutableList())}")
86+
}
87+
--
88+
89+
Which will yield the following output:
90+
91+
[source]
92+
--
93+
Added node PNode2100000001 under parent PNode1
94+
All nodes in repository: [PNode1, PNode2100000001]
95+
--
96+
97+
CAUTION: If you try to access a node that does not exist, an exception is thrown.
98+
99+
Browsing to the `model-sever` content explorer over at http://localhost:28101/repos[] and selecting _Explore Latest Version_ for _myRepository_ you should see this:
100+
101+
image::model-client-v2-sample.png[Result in `model-server` of the above code]
102+
103+
104+
For more information how to deal with `INodes` and the `client`, check the https://api.modelix.org/latest/model-api/index.html[model API] and the https://api.modelix.org/latest/model-client/org.modelix.model.client2/-model-client-v2/index.html[ModelClientV2 API] respectively.
Lines changed: 183 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,200 @@
11
= How-To start a local `model-server`
22
:navtitle: Start a `model-server`
33

4-
54
NOTE: If you are interested in a more practical usage of what is presented here, check out the https://github.com/modelix/modelix.samples[samples project^]
65

6+
NOTE: To run a light version of the `model-sever`, check out xref:core:howto/mps-model-server-plugin.adoc[]
7+
8+
== Backends: In Memory vs. Database
9+
10+
The `model-server` will by default require a database backend.
11+
The `-jdbcconf` flag allows you to provide a custom JDBC configuration file.
12+
While this setup is ideal for deployment, it might not what you need in the beginning.
13+
During development or to perform tests, it is recommended to start the `model-server` with in-memory storage.
14+
This can be achieved by adding the `-inmemory` flag to the executable.
15+
16+
17+
== Running a `model-server`
18+
19+
The following list gives an overview of the many ways to run a `model-server`:
20+
21+
22+
=== 1. Docker
23+
24+
We publish a Docker container of the `model-server` over on https://hub.docker.com/r/modelix/model-server/tags[Docker Hub^].
25+
To run the model-server container with the in-memory backend, simply call the following.
26+
[source, shell]
27+
--
28+
$ docker run --rm -p 28101:28101 modelix/modelix-model:latest -inmemory
29+
--
30+
31+
32+
=== 2. `docker-compose`
33+
34+
If you use `docker-compose`, use the following.
35+
36+
.Content of `docker-compose.yml`
37+
[source, yaml]
38+
--
39+
name: model-server-run-in-memory
40+
41+
services:
42+
model-server:
43+
image: modelix/model-server:latest0
44+
ports:
45+
- 28101:28101
46+
command: [ "-inmemory" ]
47+
--
48+
49+
Run using `docker-compose` via:
50+
51+
[source, shell]
52+
--
53+
$ docker-compose up
54+
--
55+
56+
NOTE: For more integrated examples, have a look at the xref:core:howto/metrics.adoc[metrics and monitoring] capabilities, which shows how to start the `model-server` using `docker-compose`.
57+
58+
For more complex setups, which require a database backend, you can use the following:
59+
60+
.Content of `docker-compose.yml`
61+
[source, yaml]
62+
--
63+
name: model-server-run-database
64+
65+
services:
66+
model-server:
67+
image: modelix/model-server:4.5.0
68+
restart: always
69+
healthcheck:
70+
test: ["CMD-SHELL", "curl http://localhost:28101/health"]
71+
interval: 2s
72+
timeout: 3s
73+
retries: 10
74+
depends_on:
75+
model-server-db:
76+
condition: service_healthy
77+
environment:
78+
jdbc_url: jdbc:postgresql://model-server-db:5432/modelix?currentSchema=modelix
79+
ports:
80+
- 28101:28101
81+
82+
model-server-db:
83+
image: postgres:16
84+
environment:
85+
POSTGRES_PASSWORD: modelix
86+
POSTGRES_DB: modelix
87+
POSTGRES_USER: modelix
88+
PGDATA: /var/lib/postgresql/data/pgdata
89+
healthcheck:
90+
test: ["CMD-SHELL", "pg_isready -U modelix -d modelix"]
91+
interval: 10s
92+
timeout: 3s
93+
retries: 10
94+
volumes:
95+
- model-server-db:/var/lib/postgresql/data
96+
- ./init-database.sql:/docker-entrypoint-initdb.d/init-database.sql:z
97+
98+
volumes:
99+
model-server-db: {}
100+
--
101+
102+
.Content of `init-database.sql`
103+
[source, SQL]
104+
--
105+
CREATE SCHEMA modelix;
106+
GRANT ALL ON SCHEMA modelix TO modelix;
107+
108+
CREATE TABLE modelix.model
109+
(
110+
key character varying NOT NULL,
111+
value character varying,
112+
reachable boolean,
113+
CONSTRAINT kv_pkey PRIMARY KEY (key)
114+
);
115+
GRANT ALL ON TABLE modelix.model TO modelix;
116+
--
117+
118+
Run using `docker-compose` via:
119+
120+
[source, shell]
121+
--
122+
$ docker-compose up
123+
--
124+
125+
126+
=== 3. Gradle via Dependency
127+
128+
When using Gradle, you can run a `model-server` by adding a dependency to `org.modelix:model-server`, as shown in the following minimal working example.
129+
130+
.Content of minimal `build.gradle.kts` to run a `model-server` in memory
131+
[source, kotlin]
132+
--
133+
plugins {
134+
application
135+
}
136+
137+
repositories {
138+
mavenCentral()
139+
maven { url = uri("https://artifacts.itemis.cloud/repository/maven-mps/") }
140+
}
141+
142+
dependencies {
143+
implementation("org.modelix:model-server:4.6.0")
144+
}
145+
146+
application {
147+
mainClass.set("org.modelix.model.server.Main")
148+
}
149+
150+
tasks.run.configure {
151+
args("-inmemory")
152+
// note: you can add other arguments here, e.g.
153+
// args("-inmemory", "-dumpin", "/path/to/dump/file.dump")
154+
}
155+
--
156+
157+
You can start the model-server simply by running
158+
159+
[source, bash]
160+
--
161+
./gradlew run
162+
--
163+
164+
=== 4. Gradle via Source
165+
166+
Use `git` to check out the modelix core repository from
7167

8-
- To run the model-server with default configuration run:
9-
+
10168
[source,bash]
11169
--
12-
[modelix.core] $ ./gradlew model-server:run
170+
https://github.com/modelix/modelix.core
13171
--
14172

15-
- To specify a different jdbc configuration, you can add the `-jdbcconf` arguement:
16-
+
173+
To run the model-server with default configuration run:
174+
17175
[source,bash]
18176
--
19-
[modelix.core] $ ./gradlew model-server:run --args='-jdbcconf path-to-my-database.properties'
177+
[modelix.core] $ ./gradlew model-server:run
20178
--
21179

22-
- During development or to perform tests it is recommended to start the `model-server` with in-memory storage:
23-
+
180+
NOTE: You will have to build the project first, which might take some time depending on your hardware.
181+
182+
183+
[NOTE]
184+
====
185+
To give arguments to the gradle run command, you have to add them via the `--args` flag:
186+
24187
[source,bash]
25188
--
26-
[modelix.core] $ ./gradlew model-server:run --args='-inmemory'
189+
./gradlew model-server:run --args='-jdbcconf path-to-my-database.properties -dumpout'
27190
--
191+
====
192+
193+
194+
=== 5. *In Process* (Kotlin)
195+
196+
This rather advanced version allows you to run the `model-server` inside your own application.
197+
We primarily use this approach for testing, but theoretically it could be applied elsewhere.
198+
You can find an examples of this in the following code fragment:
199+
200+
* https://github.com/modelix/modelix.core/blob/main/model-server/src/test/kotlin/org/modelix/model/server/ModelClientV2Test.kt#L48[ModelClientV2Test (modelix core tests)]

docs/global/modules/core/pages/reference/component-mps-model-server-plugin.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
https://api.modelix.org/3.12.0/mps-model-server-plugin/index.html[API doc^] | https://github.com/modelix/modelix.core[Repository^] | Artifacts: https://artifacts.itemis.cloud/service/rest/repository/browse/maven-mps/org/modelix/mps/model-server-plugin/[Nexus^] https://github.com/modelix/modelix.core/packages/1916747[GitHub Packages^]
77
--
88

9+
NOTE: Install instructions can be found in the xref:core:howto/mps-model-server-plugin.adoc[corresponding How-To].
910

1011
== Health checks
1112

docs/global/modules/core/partials/nav-howto.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
* xref:core:howto/usage-model-server.adoc[]
22
* xref:core:howto/metrics.adoc[]
33
* xref:core:howto/usage-model-api-gen-gradle.adoc[]
4+
* xref:core:howto/usage-model-client-v2.adoc[]
45
* xref:core:howto/usage-light-model-client.adoc[]
56
* xref:core:howto/testing-against-model-api.adoc[]
67
* xref:core:howto/modelql.adoc[]

0 commit comments

Comments
 (0)