a952acf3ca8bf619403407f2ba1ed8dc7646ad19
[federation.git] / gateway / src / main / java / org / acumos / federation / gateway / GatewayController.java
1 /*-
2  * ===============LICENSE_START=======================================================
3  * Acumos
4  * ===================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
6  * ===================================================================================
7  * This Acumos software file is distributed by AT&T and Tech Mahindra
8  * under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * This file is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ===============LICENSE_END=========================================================
19  */
20 package org.acumos.federation.gateway;
21
22 import java.util.List;
23 import java.util.function.Function;
24 import java.lang.invoke.MethodHandles;
25
26 import javax.servlet.http.HttpServletResponse;
27
28 import io.swagger.annotations.ApiOperation;
29
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import org.springframework.beans.factory.annotation.Autowired;
34 import org.springframework.http.MediaType;
35 import org.springframework.stereotype.Controller;
36 import org.springframework.web.bind.annotation.CrossOrigin;
37 import org.springframework.web.bind.annotation.GetMapping;
38 import org.springframework.web.bind.annotation.PathVariable;
39 import org.springframework.web.bind.annotation.PostMapping;
40 import org.springframework.web.bind.annotation.RequestMapping;
41 import org.springframework.web.bind.annotation.RequestParam;
42 import org.springframework.web.bind.annotation.ResponseBody;
43 import org.springframework.security.access.annotation.Secured;
44
45 import org.acumos.cds.domain.MLPCatalog;
46 import org.acumos.cds.domain.MLPSolution;
47 import org.acumos.cds.domain.MLPPeer;
48 import org.acumos.cds.domain.MLPPeerSubscription;
49
50 import org.acumos.federation.client.FederationClient;
51 import org.acumos.federation.client.GatewayClient;
52 import org.acumos.federation.client.data.JsonResponse;
53
54
55 /**
56  * Controller bean for the internal (gateway) API.
57  */
58 @Controller
59 @CrossOrigin
60 @Secured(Security.ROLE_INTERNAL)
61 @RequestMapping(value = GatewayClient.PEER_PFX, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
62 public class GatewayController {
63         private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
64
65         @Autowired
66         private Clients clients;
67
68         @Autowired
69         private PeerService peerService;
70
71         @Autowired
72         private SubscriptionPoller poller;
73
74         @ApiOperation(value = "Invoked by local Acumos to get a list of catalogs available from a peer Acumos instance .", response = MLPCatalog.class, responseContainer = "List")
75         @GetMapping(FederationClient.CATALOGS_URI)
76         @ResponseBody
77         public JsonResponse<List<MLPCatalog>> getCatalogs(
78             HttpServletResponse response,
79             @PathVariable("peerId") String peerId) {
80                 log.debug("/peer/{}/catalogs", peerId);
81                 return callPeer(response, peerId, FederationClient::getCatalogs);
82         }
83
84         @ApiOperation(value = "Invoked by local Acumos to get a list of solutions available from a peer Acumos instance .", response = MLPSolution.class, responseContainer = "List")
85         @GetMapping(FederationClient.SOLUTIONS_URI)
86         @ResponseBody
87         public JsonResponse<List<MLPSolution>> getSolutions(
88             HttpServletResponse response,
89             @PathVariable("peerId") String peerId,
90             @RequestParam(value="catalogId", required=true) String catalogId) {
91                 log.debug("/peer/{}/solutions", peerId);
92                 return callPeer(response, peerId, peer -> peer.getSolutions(catalogId));
93         }
94
95         @ApiOperation(value = "Invoked by local Acumos to get detailed solution information from the catalog of a peer acumos Instance.", response = MLPSolution.class)
96         @GetMapping(FederationClient.SOLUTION_URI)
97         @ResponseBody
98         public JsonResponse<MLPSolution> getSolution(
99             HttpServletResponse response,
100             @PathVariable("peerId") String peerId,
101             @PathVariable("solutionId") String solutionId) {
102                 log.debug("/peer/{}/solutions/{}", peerId, solutionId);
103                 return callPeer(response, peerId, peer -> peer.getSolution(solutionId));
104         }
105
106         @ApiOperation(value = "Invoked by local Acumos to get peers information from remote Acumos peer.", response = MLPPeer.class, responseContainer = "List")
107         @GetMapping(FederationClient.PEERS_URI)
108         @ResponseBody
109         public JsonResponse<List<MLPPeer>> getPeers(
110             HttpServletResponse response,
111             @PathVariable("peerId") String peerId) {
112                 log.debug("/peer/{}/peers", peerId);
113                 return callPeer(response, peerId, FederationClient::getPeers);
114         }
115
116         @ApiOperation(value = "Invoked by local Acumos to get peer Acumos status and information.", response = MLPPeer.class)
117         @GetMapping(FederationClient.PING_URI)
118         @ResponseBody
119         public JsonResponse<MLPPeer> ping(
120             HttpServletResponse response,
121             @PathVariable("peerId") String peerId) {
122                 log.debug("/peer/{}/ping", peerId);
123                 return callPeer(response, peerId, FederationClient::ping);
124         }
125
126         @ApiOperation(value = "Invoked by local Acumos to register with a remote Acumos peer.", response = MLPPeer.class)
127         @PostMapping(FederationClient.REGISTER_URI)
128         @ResponseBody
129         public JsonResponse<MLPPeer> register(
130             HttpServletResponse response,
131             @PathVariable("peerId") String peerId) {
132                 log.debug("/peer/{}/peer/register", peerId);
133                 return callPeer(response, peerId, FederationClient::register);
134         }
135
136         @ApiOperation("Invoked by other Acumos components in order to trigger subscription execution")
137         @PostMapping(GatewayClient.SUBSCRIPTION_URI)
138         @ResponseBody
139         public JsonResponse<Void> triggerPeerSubscription(
140             HttpServletResponse response,
141             @PathVariable("peerId") String peerId,
142             @PathVariable("subscriptionId") long subscriptionId) {
143                 log.debug("/peer/{}/subscription/{}", peerId, subscriptionId);
144                 MLPPeerSubscription subscription = peerService.getSubscription(subscriptionId);
145                 JsonResponse<Void> ret = new JsonResponse();
146                 if (subscription == null || !peerId.equals(subscription.getPeerId())) {
147                         response.setStatus(HttpServletResponse.SC_NOT_FOUND);
148                         ret.setMessage(String.format("No subscription with id %s found.", subscriptionId));
149                 } else {
150                         poller.triggerSubscription(subscription);
151                         response.setStatus(HttpServletResponse.SC_OK);
152                 }
153                 return ret;
154         }
155
156         private <T> JsonResponse<T> callPeer(HttpServletResponse response, String peerId, Function<FederationClient, T> fcn) {
157                 MLPPeer peer = peerService.getPeer(peerId);
158                 JsonResponse<T> ret = new JsonResponse();
159                 if (peer == null) {
160                         response.setStatus(HttpServletResponse.SC_NOT_FOUND);
161                         ret.setMessage(String.format("No peer with id %s found.", peerId));
162                 } else {
163                         response.setStatus(HttpServletResponse.SC_OK);
164                         ret.setContent(fcn.apply(clients.getFederationClient(peer.getApiUrl())));
165                 }
166                 return ret;
167         }
168 }