{"id":1153,"date":"2022-01-02T14:20:36","date_gmt":"2022-01-02T21:20:36","guid":{"rendered":"https:\/\/bullyrooks.com\/?p=1153"},"modified":"2022-01-04T19:54:01","modified_gmt":"2022-01-05T02:54:01","slug":"cloud-kube-simple-rest-endpoint-and-test","status":"publish","type":"post","link":"https:\/\/bullyrooks.com\/index.php\/2022\/01\/02\/cloud-kube-simple-rest-endpoint-and-test\/","title":{"rendered":"Cloud Kube | Simple REST Endpoint and Test"},"content":{"rendered":"\n<p>In the previous article we created the skeleton repo and project.  In this article we&#8217;ll be building a very basic endpoint and component test.<\/p>\n\n\n\n<p>Although I do hate hello world examples my intent is to get us to a point where we can focus on the build and deploy path.  The easiest way to do that is via a basic microservice that we can validate our deployment with.  Then we&#8217;ll iterate on our application behavior.  A basic hello world endpoint will be sufficient for that.  Additionally, this is how I would recommend building out any project that does not already have a build and deploy pipeline created.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Create a Basic Microservice Endpoint<\/h2>\n\n\n\n<p>Create a new directory under <code>src\/main\/java\/com\/bullyrooks\/cloud_application<\/code> called <code>\/controller<\/code>.  Create a new java class there called <code>HelloWorldController<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"360\" height=\"181\" src=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-8.png?resize=360%2C181&#038;ssl=1\" alt=\"\" class=\"wp-image-1154\" srcset=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-8.png?w=360&amp;ssl=1 360w, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-8.png?resize=300%2C151&amp;ssl=1 300w\" sizes=\"auto, (max-width: 360px) 100vw, 360px\" data-recalc-dims=\"1\" \/><\/figure>\n\n\n\n<p>Create a new directory under controller called <code>\/dto<\/code> and create a new java class called <code>HelloWorldResponse <\/code>in that directory.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"224\" height=\"102\" src=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-9.png?resize=224%2C102&#038;ssl=1\" alt=\"\" class=\"wp-image-1155\" data-recalc-dims=\"1\"\/><\/figure>\n\n\n\n<p>In <code>HelloWorldResponse <\/code>add this code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Data\n@NoArgsConstructor\n@AllArgsConstructor\n@Builder\npublic class HelloWorldResponse {\n    private String message;\n}<\/code><\/pre>\n\n\n\n<p>In <code>HelloWorldController <\/code>add this code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@RestController\npublic class HelloWorldController {\n\n    @GetMapping(\"\/helloworld\")\n    public HelloWorldResponse getHelloWorld(){\n        return HelloWorldResponse.builder().message(\"Hello World!\").build();\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Manual Testing<\/h2>\n\n\n\n<p>Start your application inside intellij.  Intellij should have already created an executable configuration for spring boot.  Click the green start arrow<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"212\" height=\"30\" src=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-10.png?resize=212%2C30&#038;ssl=1\" alt=\"\" class=\"wp-image-1156\" data-recalc-dims=\"1\"\/><\/figure>\n\n\n\n<p>you should see it start up in the terminal<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>2022-01-02 13:57:27.624  INFO 23284 --- &#91;  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''\n2022-01-02 13:57:27.631  INFO 23284 --- &#91;  restartedMain] c.b.cloud_application.CloudApplication   : Started CloudApplication in 1.339 seconds (JVM running for 1.961)\n<\/code><\/pre>\n\n\n\n<p>And you should be able to hit your endpoint with a <code>GET<\/code> at <code>http:\/\/localhost:8080\/helloworld<\/code>.  I recommend using postman<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"534\" height=\"417\" src=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-11.png?resize=534%2C417&#038;ssl=1\" alt=\"\" class=\"wp-image-1157\" srcset=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-11.png?w=534&amp;ssl=1 534w, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-11.png?resize=300%2C234&amp;ssl=1 300w\" sizes=\"auto, (max-width: 534px) 100vw, 534px\" data-recalc-dims=\"1\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Automated Testing<\/h2>\n\n\n\n<p>Stop your running application.  Create a new directory called <code>\/controller<\/code> under <code>src\/test\/java\/com\/bullyrooks\/cloud_a<\/code>pplication.  In that directory create a test class called <code>HelloWorldControllerTest<\/code><\/p>\n\n\n\n<p>Add this code to that class:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.bullyrooks.cloud_application.controller;\n\nimport com.bullyrooks.cloud_application.controller.dto.HelloWorldResponse;\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport lombok.extern.slf4j.Slf4j;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.boot.web.server.LocalServerPort;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\nimport org.springframework.web.client.RestTemplate;\n\nimport java.net.URI;\nimport java.net.URISyntaxException;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\n@Slf4j\n@AutoConfigureMockMvc\npublic class HelloWorldControllerTest {\n    @LocalServerPort\n    int randomServerPort;\n\n    @Test\n    void testAddCustomerSuccess() throws URISyntaxException, JsonProcessingException {\n        RestTemplate restTemplate = new RestTemplate();\n        String baseUrl = \"http:\/\/localhost:\" + randomServerPort + \"\/helloworld\";\n        URI uri = new URI(baseUrl);\n\n        HttpHeaders headers = new HttpHeaders();\n        headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);\n\n        ResponseEntity&lt;HelloWorldResponse&gt; result = restTemplate.getForEntity(uri, HelloWorldResponse.class);\n\n        \/\/Verify request succeed\n        assertEquals(200, result.getStatusCodeValue());\n        HelloWorldResponse response = result.getBody();\n        assertEquals(\"Hello World!\", response.getMessage());\n    }\n}\n\n<\/code><\/pre>\n\n\n\n<p>Right click on your test class and select <code>Run HelloWorldControllerTest<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"481\" height=\"405\" src=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-12.png?resize=481%2C405&#038;ssl=1\" alt=\"\" class=\"wp-image-1158\" srcset=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-12.png?w=481&amp;ssl=1 481w, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-12.png?resize=300%2C253&amp;ssl=1 300w\" sizes=\"auto, (max-width: 481px) 100vw, 481px\" data-recalc-dims=\"1\" \/><\/figure>\n\n\n\n<p>You should see it pass<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"368\" height=\"116\" src=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-13.png?resize=368%2C116&#038;ssl=1\" alt=\"\" class=\"wp-image-1159\" srcset=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-13.png?w=368&amp;ssl=1 368w, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-13.png?resize=300%2C95&amp;ssl=1 300w\" sizes=\"auto, (max-width: 368px) 100vw, 368px\" data-recalc-dims=\"1\" \/><\/figure>\n\n\n\n<p>This is a good place to stop.  Lets get this up on a branch.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git checkout -b microservice_dev\nSwitched to a new branch 'microservice_dev'\n\n$ git add .\n\n$ git commit -m \"endpoint and test\"\n&#91;microservice_dev 655eb72] endpoint and test\n 4 files changed, 76 insertions(+), 1 deletion(-)\n create mode 100644 src\/main\/java\/com\/bullyrooks\/cloud_application\/controller\/HelloWorldController.java\n create mode 100644 src\/main\/java\/com\/bullyrooks\/cloud_application\/controller\/dto\/HelloWorldResponse.java\n create mode 100644 src\/test\/java\/com\/bullyrooks\/cloud_application\/controller\/HelloWorldControllerTest.java\n\n$  git push --set-upstream origin microservice_dev\nEnumerating objects: 31, done.\nCounting objects: 100% (31\/31), done.\nDelta compression using up to 4 threads\nCompressing objects: 100% (13\/13), done.\nWriting objects: 100% (20\/20), 2.30 KiB | 1.15 MiB\/s, done.\nTotal 20 (delta 2), reused 0 (delta 0), pack-reused 0\nremote: Resolving deltas: 100% (2\/2), completed with 2 local objects.\nremote: \nremote: Create a pull request for 'microservice_dev' on GitHub by visiting:\nremote:      https:\/\/github.com\/bullyrooks\/cloud_application\/pull\/new\/microservice_dev\nremote:\nTo github.com-bullyrook:bullyrooks\/cloud_application.git\n * &#91;new branch]      microservice_dev -&gt; microservice_dev\nBranch 'microservice_dev' set up to track remote branch 'microservice_dev' from 'origin'.<\/code><\/pre>\n\n\n\n<p>We&#8217;re not going to push to main just yet.  I want to keep this work on a feature branch for now so that I can build out my CICD pipeline.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"entry-summary\">\nIn the previous article we created the skeleton repo and project. In&hellip;\n<\/div>\n<div class=\"link-more\"><a href=\"https:\/\/bullyrooks.com\/index.php\/2022\/01\/02\/cloud-kube-simple-rest-endpoint-and-test\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &ldquo;Cloud Kube | Simple REST Endpoint and Test&rdquo;<\/span>&hellip;<\/a><\/div>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41],"tags":[55,57,42,151],"course":[149],"class_list":["post-1153","post","type-post","status-publish","format-standard","hentry","category-software-development","tag-microservice","tag-rest","tag-spring","tag-springboot","course-kubernetes-application-hosted-in-the-cloud","entry"],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":1242,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/02\/13\/kube-cloud-pt3-synchronous-service-interaction\/","url_meta":{"origin":1153,"position":0},"title":"Kube Cloud Pt3 | Synchronous Service Interaction","author":"Bullyrook","date":"February 13, 2022","format":false,"excerpt":"In this course I'm going to show you how to make another spring boot microservice (message-generator), deploy it with our first service (cloud-application). I'll show how cloud-application service can discover message-generator via kubernetes services, call an endpoint in message-generator with a feign based REST client as well as how to\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-45.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-45.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-45.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-45.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-45.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":1161,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/01\/02\/cloud-kube-build-pipeline-initialization\/","url_meta":{"origin":1153,"position":1},"title":"Cloud Kube | Build Pipeline Initialization","author":"Bullyrook","date":"January 2, 2022","format":false,"excerpt":"Now that we have a service we're going to start building our pipeline so that as we add functionality to the application we can incorporate any build needs into the pipeline. Initialize Github Actions Create a new directory from the root of the project called .github\/workflows\/ create a file called\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-16.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-16.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-16.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-16.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-16.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":819,"url":"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-3-f03bdfe30ceb\/","url_meta":{"origin":1153,"position":2},"title":"Building a Service Layer","author":"Bullyrook","date":"March 30, 2020","format":false,"excerpt":"In this stage we\u2019re going to build out the service or logical layer of our microservice. I\u2019ll explain adapter and port or hexagonal architecture and covering the usage of mapstruct. Service Design Ports and adapter or hexagonal design is a well discussed concept, so I\u2019m not going to go into\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1115,"url":"https:\/\/bullyrooks.com\/index.php\/2021\/07\/24\/automated-terraform-deploy-using-github-actions\/","url_meta":{"origin":1153,"position":3},"title":"Automated Terraform Deploy Using Github Actions","author":"Bullyrook","date":"July 24, 2021","format":false,"excerpt":"Now we just need to build and deploy our application automatically so that whenever we push changes to the main branch, they'll automatically become available through our endpoint. Create Our Artifact Storage We're going to use a 'poor man's artifactory' to store our compiled .jar files. With our current build\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2021\/07\/image-34.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":836,"url":"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-11-636b842a3c0f\/","url_meta":{"origin":1153,"position":4},"title":"Helm for Deployment","author":"Bullyrook","date":"March 30, 2020","format":false,"excerpt":"We\u2019re about ready to deploy into kubernetes. However, deployment is not exactly straightforward. There are a lot of configuration files that we need to create and maintain in order to explain to the container management system how to deploy our application. We can use tools like kubectl to promote these\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1402,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/03\/08\/kube-cloud-pt6-fulfill-the-consumer-contract-test-for-rest-endpoint\/","url_meta":{"origin":1153,"position":5},"title":"Kube Cloud Pt6 | Fulfill the Consumer Contract Test for REST Endpoint","author":"Bullyrook","date":"March 8, 2022","format":false,"excerpt":"Now we need to fulfill our contract with the consumer. We just need to add a few pieces that that a consumer build will trigger a provider verification. Add a Verification Workflow Go back to your branch in message-generator and add a new github action workflow called verify-changed-pact.yaml with this\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/03\/image-15.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/03\/image-15.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/03\/image-15.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/1153","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/comments?post=1153"}],"version-history":[{"count":2,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/1153\/revisions"}],"predecessor-version":[{"id":1209,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/1153\/revisions\/1209"}],"wp:attachment":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/media?parent=1153"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/categories?post=1153"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/tags?post=1153"},{"taxonomy":"course","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/course?post=1153"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}