getServicesEndpointDescription()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 7
c 0
b 0
f 0
cc 1
rs 10
1
package com.hltech.judged.server.interfaces.rest.contracts;
2
3
import com.hltech.judged.server.domain.ServiceId;
4
import com.hltech.judged.server.domain.contracts.Contract;
5
import com.hltech.judged.server.domain.contracts.ServiceContracts;
6
import com.hltech.judged.server.domain.contracts.ServiceContractsRepository;
7
import com.hltech.judged.server.interfaces.rest.ResourceNotFoundException;
8
import io.swagger.annotations.ApiOperation;
9
import io.swagger.annotations.ApiResponse;
10
import io.swagger.annotations.ApiResponses;
11
import lombok.RequiredArgsConstructor;
12
import org.springframework.http.HttpStatus;
13
import org.springframework.http.MediaType;
14
import org.springframework.http.ResponseEntity;
15
import org.springframework.transaction.annotation.Transactional;
16
import org.springframework.web.bind.annotation.CrossOrigin;
17
import org.springframework.web.bind.annotation.ExceptionHandler;
18
import org.springframework.web.bind.annotation.GetMapping;
19
import org.springframework.web.bind.annotation.PathVariable;
20
import org.springframework.web.bind.annotation.PostMapping;
21
import org.springframework.web.bind.annotation.RequestBody;
22
import org.springframework.web.bind.annotation.RequestMapping;
23
import org.springframework.web.bind.annotation.ResponseStatus;
24
import org.springframework.web.bind.annotation.RestController;
25
import org.springframework.web.servlet.view.RedirectView;
26
27
import javax.persistence.NoResultException;
28
import java.util.List;
29
30
import static java.util.stream.Collectors.toList;
31
32
@RestController
33
@RequestMapping("/contracts")
34
@Transactional
35
@RequiredArgsConstructor
36
public class ContractsController {
37
38
    private final ServiceContractsRepository serviceContractsRepository;
39
40
    @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
41
    @ApiOperation(value = "Get registered contracts", nickname = "get names of services")
42
    @ApiResponses(value = {
43
        @ApiResponse(code = 302, message = "Found")
44
    })
45
    public RedirectView getServicesEndpointDescription() {
46
        return new RedirectView("contracts/services", true);
47
    }
48
49
    @GetMapping(value = "/services", produces = MediaType.APPLICATION_JSON_VALUE)
50
    @ApiOperation(value = "Get names of services with registered contracts", nickname = "get names of services")
51
    @ApiResponses(value = {
52
        @ApiResponse(code = 200, message = "Success", response = String.class, responseContainer = "list"),
53
        @ApiResponse(code = 400, message = "Bad Request"),
54
        @ApiResponse(code = 500, message = "Failure")})
55
    public List<String> getAvailableServiceNames() {
56
        return serviceContractsRepository.getServiceNames();
57
    }
58
59
    /**
60
     * This endpoint is intended to server request checking if a service with given registered any contracts.
61
     * It will be extended to provide more detailed information on a service in the future.
62
     *
63
     * @param serviceName - name of the service that we are querying for
64
     * @return name of the service if contracts are present, NOT_FOUND (404) otherwise
65
     */
66
    @GetMapping(value = "/services/{serviceName}", produces = MediaType.TEXT_PLAIN_VALUE)
67
    @ApiOperation(value = "Get details of a services with registered contracts", nickname = "get service details")
68
    @ApiResponses(value = {
69
        @ApiResponse(code = 200, message = "Success", response = String.class),
70
        @ApiResponse(code = 400, message = "Bad Request"),
71
        @ApiResponse(code = 400, message = "Not found"),
72
        @ApiResponse(code = 500, message = "Failure")})
73
    public String getAvailableServiceNames(@PathVariable(name = "serviceName") String serviceName) {
74
        return serviceContractsRepository.getService(serviceName);
75
    }
76
77
    @ExceptionHandler(NoResultException.class)
78
    @ResponseStatus(HttpStatus.NOT_FOUND)
79
    void notFound() { }
80
81
    @GetMapping(value = "/services/{serviceName}/versions", produces = MediaType.APPLICATION_JSON_VALUE)
82
    @ApiOperation(value = "Get versions of a service with registered contracts", nickname = "get versions of a service")
83
    @ApiResponses(value = {
84
        @ApiResponse(code = 200, message = "Success", response = String.class, responseContainer = "list"),
85
        @ApiResponse(code = 400, message = "Bad Request"),
86
        @ApiResponse(code = 500, message = "Failure")})
87
    public List<String> getAllServiceVersions(@PathVariable(name = "serviceName") String serviceName) {
88
        return serviceContractsRepository.findAllByServiceName(serviceName)
89
            .stream()
90
            .map(ServiceContracts::getVersion).sorted()
91
            .collect(toList());
92
    }
93
94
    @GetMapping(value = "services/{serviceName}/versions/{version:.+}", produces = MediaType.APPLICATION_JSON_VALUE)
95
    @ApiOperation(value = "Get contracts for a version of a service", nickname = "get contracts")
96
    @ApiResponses(value = {
97
        @ApiResponse(code = 200, message = "Success", response = ServiceContractsDto.class),
98
        @ApiResponse(code = 400, message = "Bad Request"),
99
        @ApiResponse(code = 500, message = "Failure")})
100
    public ServiceContractsDto getContracts(@PathVariable(name = "serviceName") String serviceName, @PathVariable(name = "version") String version) {
101
        return ServiceContractsDto.fromDomain(this.serviceContractsRepository.findOne(new ServiceId(serviceName, version)).orElseThrow(ResourceNotFoundException::new));
102
    }
103
104
    @GetMapping(value = "services/{serviceName}/versions/{version:.+}/capabilities/{protocol}", produces = MediaType.ALL_VALUE)
105
    @ApiOperation(value = "Get capabilities of a version of a service for a protocol", nickname = "get capabilities by protocol")
106
    @CrossOrigin(origins = "${contracts.cross.origin}")
107
    @ApiResponses(value = {
108
        @ApiResponse(code = 200, message = "Success", response = ServiceContractsDto.class),
109
        @ApiResponse(code = 400, message = "Bad Request"),
110
        @ApiResponse(code = 500, message = "Failure")})
111
    public ResponseEntity<String> getCapabilities(@PathVariable String serviceName, @PathVariable String version, @PathVariable(name = "protocol") String protocol) {
112
        final Contract contract = this.serviceContractsRepository
113
            .findCapabilityByServiceIdProtocol(new ServiceId(serviceName, version), protocol)
114
            .orElseThrow(ResourceNotFoundException::new);
115
        return ResponseEntity.ok().contentType(MediaType.valueOf(contract.getMimeType())).body(contract.getValue());
116
    }
117
118
    @PostMapping(value = "services/{serviceName}/versions/{version:.+}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
119
    @ApiOperation(value = "Register contracts for a version of a service", nickname = "register contracts")
120
    @ApiResponses(value = {
121
        @ApiResponse(code = 200, message = "Success", response = ServiceContractsDto.class),
122
        @ApiResponse(code = 400, message = "Bad Request"),
123
        @ApiResponse(code = 500, message = "Failure")})
124
    public ServiceContractsDto registerContract(@PathVariable(name = "serviceName") String serviceName, @PathVariable(name = "version") String version, @RequestBody ServiceContractsForm form) {
125
        return ServiceContractsDto.fromDomain(
126
            this.serviceContractsRepository.persist(form.toDomain(serviceName, version))
127
        );
128
    }
129
}
130