Skip to content

Commit fd00915

Browse files
Refactor meta and app server
1 parent 3c18611 commit fd00915

File tree

65 files changed

+2155
-244
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2155
-244
lines changed

README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@ PEERS=n1:localhost:6000,n2:localhost:6001,n3:localhost:6002
3232
ID=n0
3333
HTTP_PORT=8080
3434
META_PORT=6000
35+
REPLICATION_PORT=6050
3536

3637
./mvnw spring-boot:run -Dspring-boot.run.arguments="\
3738
--node-id={ID} \
3839
--server.address=localhost \
3940
--server.port={HTTP_PORT} \
4041
--metadata-port={META_PORT} \
42+
--replication-port={REPLICATION_PORT} \
4143
--storage=/tmp/raft-demo/{ID} \
4244
--peers={PEERS}"
4345
```
@@ -63,6 +65,7 @@ java -jar target/raft-log-replication-demo-0.0.1-SNAPSHOT.jar \
6365
--server.address=localhost \
6466
--server.port={HTTP_PORT} \
6567
--metadata-port={META_PORT} \
68+
--replication-port={REPLICATION_PORT} \
6669
--storage=/tmp/raft-demo/{ID} \
6770
--peers={PEERS}"
6871
```
@@ -78,6 +81,7 @@ java -jar target/raft-log-replication-demo-0.0.1-SNAPSHOT.jar \
7881
--server.address=localhost \
7982
--server.port=8080 \
8083
--metadata-port=6000 \
84+
--replication-port=6050 \
8185
--storage=/tmp/raft-demo/${ID} \
8286
--peers=${PEERS}
8387
@@ -87,6 +91,7 @@ java -jar target/raft-log-replication-demo-0.0.1-SNAPSHOT.jar \
8791
--server.address=localhost \
8892
--server.port=8081 \
8993
--metadata-port=6001 \
94+
--replication-port=6051 \
9095
--storage=/tmp/raft-demo/${ID} \
9196
--peers=${PEERS}
9297
@@ -96,6 +101,7 @@ java -jar target/raft-log-replication-demo-0.0.1-SNAPSHOT.jar \
96101
--server.address=localhost \
97102
--server.port=8082 \
98103
--metadata-port=6002 \
104+
--replication-port=6052 \
99105
--storage=/tmp/raft-demo/${ID} \
100106
--peers=${PEERS}
101107
```
@@ -104,6 +110,51 @@ java -jar target/raft-log-replication-demo-0.0.1-SNAPSHOT.jar \
104110
105111
See the docker-compose as well as the Dockerfile.
106112
113+
## Provisioning a partition
114+
115+
In general, a new partition of any state machine (any that implements the `StateMachine` interface) can be instantiated using the REST API:
116+
117+
```sh
118+
POST http://localhost:8080/api/cluster-manager/partitions
119+
Content-Type: application/json
120+
121+
{
122+
"stateMachineClassName": "de.umr.raft.raftlogreplicationdemo.replication.impl.statemachines.EventStoreStateMachine",
123+
"partitionName": "events",
124+
"replicationFactor": 3
125+
}
126+
```
127+
128+
For event stores, there is a convenience method to instantiate a new stream on its own partition:
129+
130+
```sh
131+
POST http://localhost:8080/api/event-store/streams
132+
Content-Type: application/json
133+
134+
{
135+
"streamName": "demo-event-store",
136+
"schema": [
137+
{
138+
"name": "SYMBOL",
139+
"type": "STRING",
140+
"properties": {}
141+
},
142+
{
143+
"name": "SECURITYTYPE",
144+
"type": "INTEGER",
145+
"properties": {}
146+
},
147+
{
148+
"name": "LASTTRADEPRICE",
149+
"type": "FLOAT",
150+
"properties": {}
151+
}
152+
]
153+
}
154+
```
155+
156+
> Note that the schema is currently ignored, since it is hardcoded. The implementation of the dynamic schema invocation is currently pending.
157+
107158
## Roadmap
108159
109160
### Make a library out of the Apache Ratis on-top abstractions

src/main/java/de/umr/raft/raftlogreplicationdemo/config/RaftConfig.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ public class RaftConfig {
3535
@Value("${storage}")
3636
@Getter private String storagePath;
3737

38-
@Value("${server.port}:8000")
38+
@Value("${server.port:8000}")
3939
@Getter private String httpPort;
4040

41-
// TODO actually, THIS is replication-port. Need also seperate, explicit port for management group
42-
@Value("${metadata-port}:6000")
43-
@Getter private String metadataPort;
44-
// or name managementPort and replicationPort ?
45-
// TODO need some kind of port proxy
41+
@Value("${metadata-port:6000}")
42+
@Getter private String managementPort;
43+
44+
@Value("${replication-port:6050}")
45+
@Getter private String replicationPort;
4646

4747
@Value("${server.address:#{null}}")
4848
private Optional<String> host;
@@ -128,4 +128,8 @@ public String getHostAddress() {
128128
public String getPublicHostAddress() {
129129
return publicHost.orElseGet(this::getHostAddress);
130130
}
131+
132+
public String getReplicationAddress() {
133+
return getHostAddress() + ":" + getReplicationPort();
134+
}
131135
}
Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
package de.umr.raft.raftlogreplicationdemo.controllers.clustermanagement;
22

3+
import de.umr.raft.raftlogreplicationdemo.models.clustermanagement.DetachPartitionRequest;
4+
import de.umr.raft.raftlogreplicationdemo.models.clustermanagement.PartitionInfoResponse;
35
import de.umr.raft.raftlogreplicationdemo.models.clustermanagement.RaftPeerRequest;
46
import de.umr.raft.raftlogreplicationdemo.models.clustermanagement.RegisterPartitionRequest;
5-
import de.umr.raft.raftlogreplicationdemo.replication.api.PartitionInfo;
7+
import de.umr.raft.raftlogreplicationdemo.models.sysinfo.ClusterHealth;
68
import de.umr.raft.raftlogreplicationdemo.services.impl.clustermanagement.ClusterManagementService;
79
import org.springframework.beans.factory.annotation.Autowired;
8-
import org.springframework.web.bind.annotation.PostMapping;
9-
import org.springframework.web.bind.annotation.RequestBody;
10-
import org.springframework.web.bind.annotation.RequestMapping;
11-
import org.springframework.web.bind.annotation.RestController;
10+
import org.springframework.web.bind.annotation.*;
11+
12+
import java.util.List;
1213

1314
@RestController
1415
@RequestMapping("/api/cluster-manager/")
@@ -18,13 +19,33 @@ public class ClusterManagementController {
1819
ClusterManagementService clusterManagementService;
1920

2021
@PostMapping(value = "/partitions")
21-
public PartitionInfo registerPartition(@RequestBody RegisterPartitionRequest registerPartitionRequest) throws ClassNotFoundException {
22+
public PartitionInfoResponse registerPartition(@RequestBody RegisterPartitionRequest registerPartitionRequest) throws ClassNotFoundException {
2223
return clusterManagementService.registerPartition(registerPartitionRequest);
2324
}
2425

26+
@DeleteMapping(value = "/partitions/{stateMachineClassname}/{partitionName}")
27+
public PartitionInfoResponse detachPartition(@PathVariable String stateMachineClassname, @PathVariable String partitionName) throws ClassNotFoundException {
28+
return clusterManagementService.detachPartition(new DetachPartitionRequest(stateMachineClassname, partitionName));
29+
}
30+
31+
@GetMapping(value = "/partitions")
32+
public List<PartitionInfoResponse> listPartitions() {
33+
return clusterManagementService.listPartitions();
34+
}
35+
36+
@GetMapping(value = "/partitions/{stateMachineClassname}")
37+
public List<PartitionInfoResponse> listPartitions(@PathVariable String stateMachineClassname) throws ClassNotFoundException {
38+
return clusterManagementService.listPartitions(stateMachineClassname);
39+
}
40+
2541
// TODO remove after test
2642
@PostMapping(value = "/heartbeat")
27-
public void sendHeartbeat(@RequestBody RaftPeerRequest raftPeerRequest) throws ClassNotFoundException {
43+
public void sendHeartbeat(@RequestBody RaftPeerRequest raftPeerRequest) {
2844
clusterManagementService.sendHeartbeat(raftPeerRequest);
2945
}
46+
47+
@GetMapping(value = "/health")
48+
public ClusterHealth getClusterHealth() {
49+
return clusterManagementService.getClusterHealth();
50+
}
3051
}

src/main/java/de/umr/raft/raftlogreplicationdemo/controllers/counter/ReplicatedCounterController.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import de.umr.raft.raftlogreplicationdemo.models.counter.CreateCounterRequest;
44
import de.umr.raft.raftlogreplicationdemo.models.sysinfo.RaftGroupInfo;
5+
import de.umr.raft.raftlogreplicationdemo.replication.api.PartitionInfo;
56
import de.umr.raft.raftlogreplicationdemo.services.impl.ReplicatedCounterService;
67
import org.springframework.beans.factory.annotation.Autowired;
78
import org.springframework.http.HttpStatus;
@@ -13,7 +14,7 @@
1314
import java.util.List;
1415
import java.util.concurrent.ExecutionException;
1516

16-
//@RestController
17+
@RestController
1718
@RequestMapping("/api/counter/replicated")
1819
public class ReplicatedCounterController {
1920

@@ -39,7 +40,7 @@ public String getCounter(@PathVariable String id) throws IOException, ExecutionE
3940
// TODO POST /api/counter/replicated?partition-size=3 creates new raft group with 3 peers
4041
@PostMapping("")
4142
@ResponseStatus(value = HttpStatus.OK)
42-
public RaftGroupInfo createNewCounter(@RequestBody CreateCounterRequest createCounterRequest) throws IOException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
43+
public PartitionInfo createNewCounter(@RequestBody CreateCounterRequest createCounterRequest) throws IOException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
4344
return counterService.createNewCounter(createCounterRequest).get();
4445
}
4546

src/main/java/de/umr/raft/raftlogreplicationdemo/controllers/eventstore/ReplicatedEventStoreController.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.util.Optional;
2020
import java.util.concurrent.ExecutionException;
2121

22+
// TODO start again once cluster management works
23+
2224
@RestController
2325
@RequestMapping("/api/event-store")
2426
public class ReplicatedEventStoreController {

src/main/java/de/umr/raft/raftlogreplicationdemo/controllers/sysinfo/performance/MeasurePerformanceController.java

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
import java.util.Optional;
1212
import java.util.concurrent.ExecutionException;
1313

14-
//@RestController
14+
@RestController
1515
@RequestMapping("/api/sys-info/performance")
1616
public class MeasurePerformanceController {
1717

1818
@Autowired MeasureEventStorePerformanceService measureEventStorePerformanceService;
19-
@Autowired MeasureCounterPerformanceService measureCounterPerformanceService;
20-
@Autowired MeasureMetadataPerformanceService measureMetadataPerformanceService;
19+
//@Autowired MeasureCounterPerformanceService measureCounterPerformanceService;
20+
//@Autowired MeasureMetadataPerformanceService measureMetadataPerformanceService;
2121

2222
// TODO remove crossOrigin later
2323
@CrossOrigin
@@ -55,36 +55,36 @@ public String runGetEventStoreStreamInfoMeasurements() throws IOException, Execu
5555
// TODO aggregate event
5656

5757
// TODO remove crossOrigin later
58-
@CrossOrigin
59-
@GetMapping("/measure/counter/replicated/increment/{count}")
60-
public String runIncrementReplicatedCounterMeasurements(@PathVariable Integer count, @RequestParam Optional<Integer> batchSize) throws IOException, ExecutionException, InterruptedException {
61-
return measureCounterPerformanceService.runIncrementReplicatedCounterMeasurements(count, batchSize).get();
62-
}
63-
64-
@GetMapping("/measure/counter/replicated/increment/sync/{count}")
65-
public String runIncrementReplicatedCounterSyncMeasurements(@PathVariable Integer count) throws IOException, ExecutionException, InterruptedException {
66-
return measureCounterPerformanceService.runIncrementReplicatedCounterSyncMeasurements(count).get();
67-
}
68-
69-
@GetMapping("/measure/counter/replicated/read")
70-
public String runReadReplicatedCounterMeasurements() throws IOException, ExecutionException, InterruptedException {
71-
return measureCounterPerformanceService.runReadReplicatedCounterMeasurements().get();
72-
}
73-
74-
@GetMapping("/measure/counter/standalone/increment/{count}")
75-
public String runIncrementStandaloneCounterMeasurements(@PathVariable Integer count) throws IOException, ExecutionException, InterruptedException {
76-
return measureCounterPerformanceService.runIncrementStandaloneCounterMeasurements(count).get();
77-
}
78-
79-
@GetMapping("/measure/counter/read")
80-
public String runReadStandaloneCounterMeasurements() throws IOException, ExecutionException, InterruptedException {
81-
return measureCounterPerformanceService.runReadStandaloneCounterMeasurements().get();
82-
}
58+
// @CrossOrigin
59+
// @GetMapping("/measure/counter/replicated/increment/{count}")
60+
// public String runIncrementReplicatedCounterMeasurements(@PathVariable Integer count, @RequestParam Optional<Integer> batchSize) throws IOException, ExecutionException, InterruptedException {
61+
// return measureCounterPerformanceService.runIncrementReplicatedCounterMeasurements(count, batchSize).get();
62+
// }
63+
//
64+
// @GetMapping("/measure/counter/replicated/increment/sync/{count}")
65+
// public String runIncrementReplicatedCounterSyncMeasurements(@PathVariable Integer count) throws IOException, ExecutionException, InterruptedException {
66+
// return measureCounterPerformanceService.runIncrementReplicatedCounterSyncMeasurements(count).get();
67+
// }
68+
//
69+
// @GetMapping("/measure/counter/replicated/read")
70+
// public String runReadReplicatedCounterMeasurements() throws IOException, ExecutionException, InterruptedException {
71+
// return measureCounterPerformanceService.runReadReplicatedCounterMeasurements().get();
72+
// }
73+
//
74+
// @GetMapping("/measure/counter/standalone/increment/{count}")
75+
// public String runIncrementStandaloneCounterMeasurements(@PathVariable Integer count) throws IOException, ExecutionException, InterruptedException {
76+
// return measureCounterPerformanceService.runIncrementStandaloneCounterMeasurements(count).get();
77+
// }
78+
//
79+
// @GetMapping("/measure/counter/read")
80+
// public String runReadStandaloneCounterMeasurements() throws IOException, ExecutionException, InterruptedException {
81+
// return measureCounterPerformanceService.runReadStandaloneCounterMeasurements().get();
82+
// }
8383

84-
@GetMapping("/measure/metadata/get")
85-
public String runGetMetadataMeasurements() throws IOException, ExecutionException, InterruptedException {
86-
return measureMetadataPerformanceService.runGetMetadataMeasurements().get();
87-
}
84+
// @GetMapping("/measure/metadata/get")
85+
// public String runGetMetadataMeasurements() throws IOException, ExecutionException, InterruptedException {
86+
// return measureMetadataPerformanceService.runGetMetadataMeasurements().get();
87+
// }
8888

8989
// TODO also test non-replicated store
9090

src/main/java/de/umr/raft/raftlogreplicationdemo/json/deserialization/InsertEventRequestDeserializer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
import java.util.Map;
2626

2727

28-
/**
29-
*
30-
*/
28+
29+
// TODO start again once cluster management works
30+
3131
@JsonComponent
3232
public class InsertEventRequestDeserializer extends JsonDeserializer<InsertEventRequest> {
3333

src/main/java/de/umr/raft/raftlogreplicationdemo/json/serialization/InsertEventRequestSerializer.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@
1414
import java.io.IOException;
1515

1616

17-
/**
18-
*
19-
*/
17+
// TODO start again once cluster management works
18+
2019
@JsonComponent
2120
public class InsertEventRequestSerializer extends JsonSerializer<InsertEventRequest> {
2221

src/main/java/de/umr/raft/raftlogreplicationdemo/models/CreatePartitionRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
// TODO obsolete, use RegisterPartitionRequest
44
public interface CreatePartitionRequest {
55

6-
abstract long getPartitionsCount();
6+
abstract int getPartitionsCount();
77

88
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package de.umr.raft.raftlogreplicationdemo.models.clustermanagement;
2+
3+
import lombok.Getter;
4+
import lombok.NonNull;
5+
import lombok.RequiredArgsConstructor;
6+
import org.apache.ratis.statemachine.impl.BaseStateMachine;
7+
8+
@RequiredArgsConstructor
9+
public class DetachPartitionRequest {
10+
@Getter @NonNull final String stateMachineClassName;
11+
@Getter @NonNull final String partitionName;
12+
13+
public Class<? extends BaseStateMachine> getStateMachineClass() throws ClassNotFoundException {
14+
return Class.forName(stateMachineClassName).asSubclass(BaseStateMachine.class);
15+
}
16+
}

0 commit comments

Comments
 (0)