> queryParams = new HashMap<>();
38 | private final PathExtractor extractor = new PathExtractor();
39 |
40 | @Before
41 | public void setUp() throws Exception {
42 | when(requestContext.getRequest()).thenReturn(servletRequest);
43 | when(servletRequest.getContextPath()).thenReturn("/root");
44 | when(servletRequest.getServletPath()).thenReturn("/path/to/resource");
45 |
46 | queryParams.put("n", asList("3", "5"));
47 | }
48 |
49 | @Test
50 | public void extractsPathWithQueryStringAndPathInfo() {
51 | when(servletRequest.getPathInfo()).thenReturn("/id");
52 | when(requestContext.getRequestQueryParams()).thenReturn(queryParams);
53 |
54 | String path = extractor.path(requestContext);
55 |
56 | assertThat(path).isEqualTo("/root/path/to/resource/id?n=3&n=5");
57 | }
58 | }
--------------------------------------------------------------------------------
/scripts/make_docker_image/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM openjdk:8-jre-alpine
2 |
3 | EXPOSE 8080
4 |
5 | RUN mkdir -p /maven/company/
6 |
7 | COPY ./*-exec.jar /maven/company/
8 |
9 | ENTRYPOINT java $JAVA_OPTS -jar /maven/company/$ARTIFACT_ID-0.2.0-SNAPSHOT-exec.jar
10 |
--------------------------------------------------------------------------------
/stress-tests/README.md:
--------------------------------------------------------------------------------
1 | # Steps to stress tests *Company Demo* using JMeter
2 |
3 | 1. make sure the *Company Demo* is up
4 | 2. replace host and port information in `hosts.csv` file with the working *Company Demo*'s.
5 | 3. run JMeter tests
6 | ```bash
7 | jmeter -n -t workshop.jmx -j workshop.log -l workshop.jtl -Jthreads=100 -Jduration=600
8 | ```
9 | The threads parameter means the simulated concurrency while the duration means the test period.
10 |
11 | After the tests finished, you can check the result in jmeter's user interface by calling `jmeter` directly and import the *workshop.jmx* file.
12 |
--------------------------------------------------------------------------------
/stress-tests/hosts.csv:
--------------------------------------------------------------------------------
1 | 127.0.0.1,8083
2 |
--------------------------------------------------------------------------------
/worker/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
21 |
22 | company
23 | io.servicecomb.workshop.demo
24 | 0.3.0-SNAPSHOT
25 |
26 | 4.0.0
27 |
28 | worker
29 |
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-logging
38 |
39 |
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-log4j2
44 |
45 |
46 | org.apache.logging.log4j
47 | log4j-web
48 |
49 |
50 | com.lmax
51 | disruptor
52 |
53 |
54 | org.springframework.boot
55 | spring-boot-starter-web
56 |
57 |
58 | io.servicecomb
59 | spring-boot-starter-provider
60 |
61 |
62 | io.servicecomb
63 | handler-tracing-zipkin
64 |
65 |
66 |
67 | org.springframework.boot
68 | spring-boot-starter-test
69 | test
70 |
71 |
72 | com.github.seanyinx
73 | unit-scaffolding
74 | test
75 |
76 |
77 |
78 |
79 |
80 |
81 | com.github.odavid.maven.plugins
82 | mixin-maven-plugin
83 |
84 |
85 |
86 | io.servicecomb.workshop.demo
87 | docker-build-config
88 | 0.3.0-SNAPSHOT
89 |
90 |
91 |
92 |
93 |
94 | org.springframework.boot
95 | spring-boot-maven-plugin
96 |
97 |
98 |
99 |
100 |
101 |
102 | docker
103 |
104 |
105 |
106 | io.fabric8
107 | docker-maven-plugin
108 |
109 |
110 | org.commonjava.maven.plugins
111 | directory-maven-plugin
112 |
113 |
114 |
115 |
116 |
117 | HuaweiCloud
118 |
119 |
120 |
121 | maven-antrun-plugin
122 | 1.8
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/worker/src/main/java/io/servicecomb/company/worker/FibonacciEndpoint.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Huawei Technologies Co., Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.servicecomb.company.worker;
17 |
18 | /**
19 | * {@link FibonacciEndpoint} provides the common interface for different endpoint implementations,
20 | * such as {@link FibonacciRestEndpoint} and {@link FibonacciRpcEndpoint}.
21 | *
22 | * It supports sequence up to roughly 90, because the sequence value will exceed the limit of Java
23 | * type long.
24 | *
25 | * The endpoints are supposed to be very thin. They parse requests from different protocols and
26 | * delegate them to the same calculation logic provided by {@link FibonacciService}.
27 | */
28 | public interface FibonacciEndpoint {
29 |
30 | /**
31 | * Calculates the nth term of fibonacci sequence.
32 | * for example, the following statement outputs fibonacci sequence [0, 1, 1, 2, 3, 5]
33 | *
34 | * {@code long[] sequence = {
35 | * endpoint.term(0),
36 | * endpoint.term(1),
37 | * endpoint.term(2),
38 | * endpoint.term(3),
39 | * endpoint.term(4),
40 | * endpoint.term(5)};
41 | * System.out.println(Arrays.toString(sequence));
42 | * }
43 | *
44 | *
45 | * @param n the index of fibonacci sequence
46 | * @return the nth term of fibonacci
47 | */
48 | long term(int n);
49 | }
50 |
--------------------------------------------------------------------------------
/worker/src/main/java/io/servicecomb/company/worker/FibonacciRestEndpoint.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Huawei Technologies Co., Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.servicecomb.company.worker;
17 |
18 | import io.servicecomb.provider.rest.common.RestSchema;
19 | import org.springframework.beans.factory.annotation.Autowired;
20 | import org.springframework.stereotype.Controller;
21 | import org.springframework.web.bind.annotation.RequestMapping;
22 | import org.springframework.web.bind.annotation.RequestMethod;
23 | import org.springframework.web.bind.annotation.ResponseBody;
24 |
25 | /**
26 | * {@link FibonacciRestEndpoint} provides the rest implementation of {@link FibonacciEndpoint}.
27 | * The rest endpoint is accessed by /fibonacci/term?n={value} with HTTP GET.
28 | */
29 | @RestSchema(schemaId = "fibonacciRestEndpoint")
30 | @RequestMapping("/fibonacci")
31 | @Controller
32 | public class FibonacciRestEndpoint implements FibonacciEndpoint {
33 |
34 | private final FibonacciService fibonacciService;
35 |
36 | @Autowired
37 | FibonacciRestEndpoint(FibonacciService fibonacciService) {
38 | this.fibonacciService = fibonacciService;
39 | }
40 |
41 | @Override
42 | @RequestMapping(value = "/term", method = RequestMethod.GET)
43 | @ResponseBody
44 | public long term(int n) {
45 | return fibonacciService.term(n);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/worker/src/main/java/io/servicecomb/company/worker/FibonacciRpcEndpoint.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Huawei Technologies Co., Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.servicecomb.company.worker;
17 |
18 |
19 | import io.servicecomb.provider.pojo.RpcSchema;
20 | import org.springframework.beans.factory.annotation.Autowired;
21 |
22 | /**
23 | * {@link FibonacciRpcEndpoint} provides the RPC implementation of {@link FibonacciEndpoint}.
24 | */
25 | @RpcSchema(schemaId = "fibonacciRpcEndpoint")
26 | // class modifier has to be public, or producer invoker will fail to access it
27 | public class FibonacciRpcEndpoint implements FibonacciEndpoint {
28 |
29 | private final FibonacciService fibonacciService;
30 |
31 | @Autowired
32 | public FibonacciRpcEndpoint(FibonacciService fibonacciService) {
33 | this.fibonacciService = fibonacciService;
34 | }
35 |
36 | @Override
37 | public long term(int n) {
38 | return fibonacciService.term(n);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/worker/src/main/java/io/servicecomb/company/worker/FibonacciService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Huawei Technologies Co., Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.servicecomb.company.worker;
17 |
18 | /**
19 | * {@link FibonacciService} provides the interface of actual fibonacci sequence calculation.
20 | */
21 | interface FibonacciService {
22 |
23 | /**
24 | * @see FibonacciEndpoint#term(int)
25 | * @param n the index of fibonacci sequence
26 | * @return the nth term of fibonacci sequence
27 | */
28 | long term(int n);
29 | }
30 |
--------------------------------------------------------------------------------
/worker/src/main/java/io/servicecomb/company/worker/FibonacciServiceImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Huawei Technologies Co., Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.servicecomb.company.worker;
17 |
18 | import org.springframework.stereotype.Service;
19 |
20 | @Service
21 | class FibonacciServiceImpl implements FibonacciService {
22 |
23 | /**
24 | * {@inheritDoc}
25 | */
26 | @Override
27 | public long term(int n) {
28 | if (n < 0) {
29 | throw new IllegalArgumentException("Fibonacci term must not be negative: " + n);
30 | }
31 |
32 | return nthTerm(n, new long[]{-1, -1});
33 | }
34 |
35 | private long nthTerm(int n, long[] lastTwoFibos) {
36 | if (n == 0) {
37 | return 0;
38 | } else if (n == 1) {
39 | return 1;
40 | }
41 |
42 | if (!isCached(lastTwoFibos)) {
43 | cacheCalculatedFibo(nthTerm(n - 2, lastTwoFibos), lastTwoFibos);
44 | cacheCalculatedFibo(nthTerm(n - 1, lastTwoFibos), lastTwoFibos);
45 | }
46 |
47 | return lastTwoFibos[0] + lastTwoFibos[1];
48 | }
49 |
50 | private boolean isCached(long[] lastTwoFibos) {
51 | return lastTwoFibos[0] >= 0 && lastTwoFibos[1] >= 0;
52 | }
53 |
54 | private void cacheCalculatedFibo(long fibo, long[] lastTwoFibos) {
55 | lastTwoFibos[1] = lastTwoFibos[0];
56 | lastTwoFibos[0] = fibo;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/worker/src/main/java/io/servicecomb/company/worker/WorkerApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Huawei Technologies Co., Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.servicecomb.company.worker;
17 |
18 | import io.servicecomb.springboot.starter.provider.EnableServiceComb;
19 | import org.springframework.boot.SpringApplication;
20 | import org.springframework.boot.autoconfigure.SpringBootApplication;
21 | import org.springframework.context.annotation.Configuration;
22 | import org.springframework.context.annotation.Profile;
23 |
24 | @SpringBootApplication
25 | public class WorkerApplication {
26 |
27 | public static void main(String[] args) {
28 | SpringApplication.run(WorkerApplication.class, args);
29 | }
30 |
31 | // do not enable service registration/discovery and schema generation/registration
32 | // unless the active profile is not dev
33 | @EnableServiceComb
34 | @Profile("!dev")
35 | @Configuration
36 | static class ServiceCombConfig {
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/worker/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 0
3 |
--------------------------------------------------------------------------------
/worker/src/main/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/worker/src/main/resources/microservice.yaml:
--------------------------------------------------------------------------------
1 | # all interconnected microservices must belong to an application wth the same ID
2 | APPLICATION_ID: company
3 | service_description:
4 | # name of the declaring microservice
5 | name: worker
6 | version: 0.0.1
7 | cse:
8 | service:
9 | registry:
10 | address: http://sc.servicecomb.io:30100
11 | highway:
12 | address: 0.0.0.0:7070
13 | rest:
14 | address: 0.0.0.0:8080
15 | handler:
16 | chain:
17 | Provider:
18 | default: tracing-provider,bizkeeper-provider
19 |
20 | servicecomb:
21 | tracing:
22 | collector:
23 | address: http://zipkin.io:9411
24 |
--------------------------------------------------------------------------------
/worker/src/test/java/io/servicecomb/company/worker/FibonacciRestEndpointTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Huawei Technologies Co., Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.servicecomb.company.worker;
17 |
18 | import static org.mockito.Mockito.when;
19 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
20 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
21 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
22 |
23 | import com.seanyinx.github.unit.scaffolding.Randomness;
24 | import org.junit.Test;
25 | import org.junit.runner.RunWith;
26 | import org.springframework.beans.factory.annotation.Autowired;
27 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
28 | import org.springframework.boot.test.mock.mockito.MockBean;
29 | import org.springframework.test.context.ActiveProfiles;
30 | import org.springframework.test.context.junit4.SpringRunner;
31 | import org.springframework.test.web.servlet.MockMvc;
32 |
33 | @RunWith(SpringRunner.class)
34 | @WebMvcTest(FibonacciRestEndpoint.class)
35 | @ActiveProfiles("dev")
36 | public class FibonacciRestEndpointTest {
37 | private final long expected = Randomness.nextLong();
38 | private final int term = Randomness.nextInt();
39 |
40 | @MockBean
41 | private FibonacciService fibonacciService;
42 |
43 | @Autowired
44 | private MockMvc mockMvc;
45 |
46 | @Test
47 | public void returnsTokenOfAuthenticatedUser() throws Exception {
48 | when(fibonacciService.term(term)).thenReturn(expected);
49 |
50 | mockMvc.perform(
51 | get("/fibonacci/term")
52 | .param("n", String.valueOf(term)))
53 | .andExpect(status().isOk())
54 | .andExpect(content().string(String.valueOf(expected)));
55 | }
56 | }
--------------------------------------------------------------------------------
/worker/src/test/java/io/servicecomb/company/worker/FibonacciRpcEndpointTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Huawei Technologies Co., Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package io.servicecomb.company.worker;
18 |
19 | import static org.assertj.core.api.Assertions.assertThat;
20 | import static org.mockito.Mockito.when;
21 |
22 | import com.seanyinx.github.unit.scaffolding.Randomness;
23 | import org.junit.Test;
24 | import org.mockito.Mockito;
25 |
26 | public class FibonacciRpcEndpointTest {
27 |
28 | private final FibonacciService fibonacciService = Mockito.mock(FibonacciService.class);
29 |
30 | private final long expected = Randomness.nextLong();
31 | private final int term = Randomness.nextInt();
32 |
33 | private final FibonacciRpcEndpoint fibonacciRpcApi = new FibonacciRpcEndpoint(fibonacciService);
34 |
35 | @Test
36 | public void providesFibonacciTermWithUnderlyingService() {
37 | when(fibonacciService.term(term)).thenReturn(expected);
38 |
39 | long fibo = fibonacciRpcApi.term(term);
40 |
41 | assertThat(fibo).isEqualTo(expected);
42 | }
43 | }
--------------------------------------------------------------------------------
/worker/src/test/java/io/servicecomb/company/worker/FibonacciServiceTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Huawei Technologies Co., Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package io.servicecomb.company.worker;
17 |
18 | import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
19 | import static com.seanyinx.github.unit.scaffolding.Randomness.nextInt;
20 | import static org.assertj.core.api.Assertions.assertThat;
21 |
22 | import org.junit.Test;
23 |
24 | public class FibonacciServiceTest {
25 |
26 | private final int[] expected = {
27 | 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765,
28 | 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811
29 | };
30 |
31 | private final FibonacciService calculator = new FibonacciServiceImpl();
32 |
33 | @Test
34 | public void calculatesFibonacciOfTermN() {
35 | for (int i = 0, length = expected.length; i < length; i++) {
36 | long fib = calculator.term(i);
37 |
38 | assertThat(fib).isEqualTo(expected[i]);
39 | }
40 | }
41 |
42 | @Test
43 | public void blowsUpWhenInputIsNegative() {
44 | int term = -nextInt(128) - 1;
45 | try {
46 | calculator.term(term);
47 | expectFailing(IllegalArgumentException.class);
48 | } catch (IllegalArgumentException e) {
49 | assertThat(e.getMessage()).isEqualTo("Fibonacci term must not be negative: " + term);
50 | }
51 | }
52 |
53 | @Test
54 | public void calculatesFibonacciOfTerm90() {
55 | long fibo = calculator.term(90);
56 |
57 | assertThat(fibo).isEqualTo(2880067194370816120L);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------