Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/build_integration_and_code_analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ jobs:
Build-Test:
name: Integration Test
runs-on: ubuntu-latest
permissions:
checks: write

steps:
- uses: actions/checkout@v3

Expand All @@ -67,7 +70,8 @@ jobs:
run: mvn clean verify

- name: Publish test coverage results
uses: PavanMudigonda/jacoco-reporter@v4.5
id: jacoco_reporter
uses: PavanMudigonda/jacoco-reporter@v4.6
with:
coverage_results_path: 'target/site/jacoco/jacoco.xml'
coverage_report_title: 'Test coverage results'
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Answer King REST API

The Answer King REST API is the backend for a fast food business. It allows items and categories to be created and
orders to be placed. An item can be included in multiple categories.
The Answer King REST API is the backend for a fast food business. It allows products and categories to be created and
orders to be placed. A product can be included in multiple categories.

## Docker

Expand All @@ -26,7 +26,7 @@ and execute the following commands:

[Docker Compose](https://docs.docker.com/compose/install/)

[AMAZON CORRETTO 17](https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/downloads-list.html/)
[AMAZON CORRETTO 17](https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/downloads-list.html)

## Maven

Expand All @@ -52,7 +52,7 @@ If Maven isn't installed on your system, the Maven Wrapper can be used by using

### Prerequisites

[AMAZON CORRETTO 17](https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/downloads-list.html/)
[AMAZON CORRETTO 17](https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/downloads-list.html)

## MySQL

Expand Down
14 changes: 7 additions & 7 deletions init_scripts/schema.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CREATE TABLE IF NOT EXISTS item (
CREATE TABLE IF NOT EXISTS product (
id BIGINT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
description VARCHAR(255) NOT NULL,
Expand All @@ -16,13 +16,13 @@ CREATE TABLE IF NOT EXISTS category (
PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS item_category (
CREATE TABLE IF NOT EXISTS product_category (
id BIGINT NOT NULL AUTO_INCREMENT,
item_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,
category_id BIGINT NOT NULL,

PRIMARY KEY (id),
FOREIGN KEY (item_id) REFERENCES item(id),
FOREIGN KEY (product_id) REFERENCES product(id),
FOREIGN KEY (category_id) REFERENCES category(id)
);

Expand All @@ -34,13 +34,13 @@ CREATE TABLE IF NOT EXISTS `order` (
PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS order_item (
CREATE TABLE IF NOT EXISTS order_product (
id BIGINT NOT NULL AUTO_INCREMENT,
order_id BIGINT NOT NULL,
item_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,
quantity INT NOT NULL,

PRIMARY KEY (id),
FOREIGN KEY (order_id) REFERENCES `order`(id),
FOREIGN KEY (item_id) REFERENCES item(id)
FOREIGN KEY (product_id) REFERENCES product(id)
);
35 changes: 26 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,9 @@
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.12</version>
</dependency>

<dependency>
Expand All @@ -84,6 +78,11 @@
<artifactId>mapstruct</artifactId>
<version>1.5.3.Final</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-security</artifactId>
<version>1.6.12</version>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -185,6 +184,24 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-maven-plugin</artifactId>
<version>0.2</version>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<apiDocsUrl>http://localhost:8080/api-docs</apiDocsUrl>
<outputFileName>openapi.yml</outputFileName>
<outputDir>${project.build.directory}</outputDir>
</configuration>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
Expand Down Expand Up @@ -50,4 +51,15 @@ public InMemoryUserDetailsManager userDetailsManager() {

return new InMemoryUserDetailsManager(paul, john, ringo, george);
}

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web
.ignoring()
.antMatchers("/")
.antMatchers("/api/swagger/**”,”/api/swagger-ui/**”,”/api/swagger-ui.html”," +
"/api/swagger-ui-custom.html", "/webjars/**", "/api/swagger-resources/**",
"/api/configuration/**”, ”/api/api-docs/**");
}

}
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
package com.answerdigital.academy.answerking.config;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

@Configuration
public class SwaggerConfig {

@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("public-apis")
.pathsToMatch("/**")
.pathsToExclude("/admins/**")
.build();
}

@Bean
public Docket swagger() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
public GroupedOpenApi actuatorApi() {
return GroupedOpenApi.builder()
.group("admins")
.pathsToMatch("/admins/**")
.build();
}

@Bean
public OpenAPI springShopOpenAPI() {
return new OpenAPI()
.info(new Info().title("AnswerKing API")
.description("Answer King application")
.version("v0.0.1")
.license(new License().name("Apache 2.0").url("http://springdoc.org")));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
import com.answerdigital.academy.answerking.request.AddCategoryRequest;
import com.answerdigital.academy.answerking.request.UpdateCategoryRequest;
import com.answerdigital.academy.answerking.service.CategoryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand Down Expand Up @@ -41,22 +46,27 @@ public ResponseEntity<Category> addCategory(@Valid @RequestBody final AddCategor
errors.hasErrors() ? HttpStatus.BAD_REQUEST : HttpStatus.OK);
}

@Operation(summary = "Get all categories.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Found the the list of categories",
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = Category.class)) })
})
@GetMapping
public ResponseEntity<Collection<Category>> getAllCategories() {
final Set<Category> categories = categoryService.findAll();
return new ResponseEntity<>(categories, categories.isEmpty() ? HttpStatus.NO_CONTENT : HttpStatus.OK);
}

@PutMapping("/{categoryId}/additem/{itemId}")
public ResponseEntity<Category> addItemToCategory(@PathVariable @NotNull final Long categoryId,
@PathVariable @NotNull final Long itemId) {
return new ResponseEntity<>(categoryService.addItemToCategory(categoryId, itemId), HttpStatus.OK);
@PutMapping("/{categoryId}/addproduct/{productId}")
public ResponseEntity<Category> addProductToCategory(@PathVariable @NotNull final Long categoryId,
@PathVariable @NotNull final Long productId) {
return new ResponseEntity<>(categoryService.addProductToCategory(categoryId, productId), HttpStatus.OK);
}

@PutMapping("/{categoryId}/removeitem/{itemId}")
public ResponseEntity<Category> removeItemFromCategory(@PathVariable @NotNull final Long categoryId,
@PathVariable @NotNull final Long itemId) {
return new ResponseEntity<>(categoryService.removeItemFromCategory(categoryId, itemId), HttpStatus.OK);
@PutMapping("/{categoryId}/removeproduct/{productId}")
public ResponseEntity<Category> removeProductFromCategory(@PathVariable @NotNull final Long categoryId,
@PathVariable @NotNull final Long productId) {
return new ResponseEntity<>(categoryService.removeProductFromCategory(categoryId, productId), HttpStatus.OK);
}

@PutMapping("/{categoryId}")
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,23 @@ public ResponseEntity<List<Order>> getAllOrders() {
return new ResponseEntity<>(foundOrders, foundOrders.isEmpty() ? HttpStatus.NO_CONTENT : HttpStatus.OK);
}

@PostMapping(path = "/{orderId}/item/{itemId}/quantity/{quantity}")
public ResponseEntity<Order> addItemToBasket(@PathVariable @NotNull final Long orderId,
@PathVariable @NotNull final Long itemId,
@PathVariable @NotNull final Integer quantity) {
return new ResponseEntity<>(orderService.addItemToBasket(orderId, itemId, quantity), HttpStatus.OK);
@PostMapping(path = "/{orderId}/product/{productId}/quantity/{quantity}")
public ResponseEntity<Order> addProductToBasket(@PathVariable @NotNull final Long orderId,
@PathVariable @NotNull final Long productId,
@PathVariable @NotNull final Integer quantity) {
return new ResponseEntity<>(orderService.addProductToBasket(orderId, productId, quantity), HttpStatus.OK);
}

@DeleteMapping(path = "/{orderId}/item/{itemId}")
public ResponseEntity<Order> deleteItemInBasket(@PathVariable @NotNull final Long orderId,
@PathVariable @NotNull final Long itemId) {
return new ResponseEntity<>(orderService.deleteItemInBasket(orderId, itemId), HttpStatus.OK);
@DeleteMapping(path = "/{orderId}/product/{productId}")
public ResponseEntity<Order> deleteProductInBasket(@PathVariable @NotNull final Long orderId,
@PathVariable @NotNull final Long productId) {
return new ResponseEntity<>(orderService.deleteProductInBasket(orderId, productId), HttpStatus.OK);
}

@PutMapping(path = "/{orderId}/item/{itemId}/quantity/{quantity}")
public ResponseEntity<Order> updateItemQuantity(@PathVariable @NotNull final Long orderId,
@PathVariable @NotNull final Long itemId,
@PathVariable @NotNull final Integer quantity) {
return new ResponseEntity<>(orderService.updateItemQuantity(orderId, itemId, quantity), HttpStatus.OK);
@PutMapping(path = "/{orderId}/product/{productId}/quantity/{quantity}")
public ResponseEntity<Order> updateProductQuantity(@PathVariable @NotNull final Long orderId,
@PathVariable @NotNull final Long productId,
@PathVariable @NotNull final Integer quantity) {
return new ResponseEntity<>(orderService.updateProductQuantity(orderId, productId, quantity), HttpStatus.OK);
}
}
Loading