Refine access control, peer access
[federation.git] / gateway / src / main / java / org / acumos / federation / gateway / controller / CatalogController.java
1 /*-
2  * ===============LICENSE_START=======================================================
3  * Acumos
4  * ===================================================================================
5  * Copyright (C) 2017 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
21 package org.acumos.federation.gateway.controller;
22
23 import java.util.List;
24
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27
28 import org.springframework.beans.factory.annotation.Autowired;
29 import org.springframework.core.io.InputStreamResource;
30 import org.springframework.http.HttpEntity;
31 import org.springframework.http.MediaType;
32 import org.springframework.http.ResponseEntity;
33 import org.springframework.security.access.prepost.PreAuthorize;
34 import org.springframework.security.core.context.SecurityContextHolder;
35 import org.springframework.stereotype.Controller;
36 import org.springframework.web.util.UriComponentsBuilder;
37 import org.springframework.web.bind.annotation.CrossOrigin;
38 import org.springframework.web.bind.annotation.PathVariable;
39 import org.springframework.web.bind.annotation.RequestMapping;
40 import org.springframework.web.bind.annotation.RequestMethod;
41 import org.springframework.web.bind.annotation.RequestParam;
42 import org.springframework.web.bind.annotation.ResponseBody;
43
44 import org.acumos.cds.domain.MLPArtifact;
45 import org.acumos.cds.domain.MLPSolution;
46 import org.acumos.cds.domain.MLPSolutionRevision;
47 import org.acumos.federation.gateway.common.JSONTags;
48 import org.acumos.federation.gateway.common.JsonResponse;
49 import org.acumos.federation.gateway.config.APINames;
50 import org.acumos.federation.gateway.config.EELFLoggerDelegate;
51 import org.acumos.federation.gateway.service.CatalogService;
52 import org.acumos.federation.gateway.service.ServiceContext;
53 import org.acumos.federation.gateway.security.Peer;
54
55 import io.swagger.annotations.ApiOperation;
56
57 /**
58  * 
59  *
60  */
61 @Controller
62 @RequestMapping("/")
63 public class CatalogController extends AbstractController {
64         
65         
66         @Autowired
67         CatalogService catalogService;
68         
69         
70 //      /**
71 //       * @param request
72 //       *            HttpServletRequest
73 //       * @param response
74 //       *                      HttpServletResponse
75 //       * @return List of Published ML Solutions in JSON format.
76 //       */
77 //      @CrossOrigin
78 //      @ApiOperation(value = "Invoked by Peer Acumos to get a Paginated list of Published Solutions from the Catalog of the local Acumos Instance .", response = MLPSolution.class, responseContainer = "Page")
79 //      @RequestMapping(value = {APINames.PEER_SOLUTIONS}, method = RequestMethod.GET, produces = APPLICATION_JSON)
80 //      @ResponseBody
81 //      public JsonResponse<RestPageResponse<MLPSolution>> getSolutionsListFromPeer(HttpServletRequest request, HttpServletResponse response,
82 //                      @RequestParam("pageNumber") Integer pageNumber, @RequestParam("maxSize") Integer maxSize, 
83 //                      @RequestParam(required = false) String sortingOrder, @RequestParam(required = false) String mlpModelTypes) {
84 //              JsonResponse<RestPageResponse<MLPSolution>> data = null;
85 //              RestPageResponse<MLPSolution> peerCatalogSolutions = null;
86 //              try {
87 //                      data = new JsonResponse<RestPageResponse<MLPSolution>>();
88 //                      peerCatalogSolutions = federationGatewayService.getPeerCatalogSolutions(pageNumber, maxSize, sortingOrder, null);
89 //                      if(peerCatalogSolutions != null) {
90 //                              data.setResponseBody(peerCatalogSolutions);
91 //                              logger.debug(EELFLoggerDelegate.debugLogger, "getSolutionsListFromPeer: size is {} ");
92 //                      }
93 //              } catch (Exception e) {
94 //                      logger.error(EELFLoggerDelegate.errorLogger, "Exception Occurred Fetching Solutions for Market Place Catalog", e);
95 //              }
96 //              return data;
97 //      }
98         
99         /**
100          * @param request
101          *            HttpServletRequest
102          * @param response
103          *                      HttpServletResponse
104          * @return List of Published ML Solutions in JSON format.
105          */
106         @CrossOrigin
107 //@PreAuthorize("hasAuthority('PEER')"
108         @PreAuthorize("hasAuthority(T(org.acumos.federation.gateway.security.Priviledge).CATALOG_ACCESS)")
109         @ApiOperation(value = "Invoked by Peer Acumos to get a list of Published Solutions from the Catalog of the local Acumos Instance .", response = MLPSolution.class, responseContainer = "List")
110         @RequestMapping(value = {APINames.PEER_SOLUTIONS}, method = RequestMethod.GET, produces = APPLICATION_JSON)
111         @ResponseBody
112         public JsonResponse<List<MLPSolution>> getSolutions(
113                         /* HttpServletRequest theHttpRequest,*/
114                         HttpServletResponse theHttpResponse,
115                         @RequestParam(value = "modelTypeCode", required = false) String mlpModelTypes) {
116                 JsonResponse<List<MLPSolution>> response = null;
117                 List<MLPSolution> peerCatalogSolutions = null;
118                 log.debug(EELFLoggerDelegate.debugLogger, APINames.PEER_SOLUTIONS);
119                 try {
120                         response = new JsonResponse<List<MLPSolution>>();
121                         log.debug(EELFLoggerDelegate.debugLogger, "getSolutionsListFromPeer: model types " + mlpModelTypes);
122                         peerCatalogSolutions = catalogService.getSolutions(mlpModelTypes, new ControllerContext());
123                         if(peerCatalogSolutions != null) {
124                                 response.setResponseBody(peerCatalogSolutions);
125                                 response.setResponseCode(String.valueOf(HttpServletResponse.SC_OK));
126                                 response.setResponseDetail(JSONTags.TAG_STATUS_SUCCESS);
127                                 response.setStatus(true);
128                                 theHttpResponse.setStatus(HttpServletResponse.SC_OK);
129                                 log.debug(EELFLoggerDelegate.debugLogger, "getSolutions: size is " + peerCatalogSolutions.size());
130                         }
131                 } catch (Exception e) {
132                         response.setResponseCode(String.valueOf(HttpServletResponse.SC_BAD_REQUEST));
133                         response.setResponseDetail(JSONTags.TAG_STATUS_FAILURE);
134                         response.setStatus(false);
135                         theHttpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
136                         log.error(EELFLoggerDelegate.errorLogger, "Exception occurred fetching Solutions for Market Place Catalog", e);
137                 }
138                 return response;
139         }
140
141         @CrossOrigin
142         @PreAuthorize("hasAuthority('CATALOG_ACCESS')")
143         @ApiOperation(value = "Invoked by Peer Acumos to get a list detailed solution information from the Catalog of the local Acumos Instance .", response = MLPSolution.class)
144         @RequestMapping(value = {APINames.PEER_SOLUTION_DETAILS}, method = RequestMethod.GET, produces = APPLICATION_JSON)
145         @ResponseBody
146         public JsonResponse<MLPSolution> getSolutionDetails(
147                         HttpServletResponse theHttpResponse,
148                         @PathVariable(value="solutionId") String theSolutionId) {
149                 JsonResponse<MLPSolution> response = null;
150                 MLPSolution solution = null;
151                 log.debug(EELFLoggerDelegate.debugLogger, APINames.PEER_SOLUTION_DETAILS + ": " + theSolutionId);
152                 try {
153                         response = new JsonResponse<MLPSolution>();
154                         solution = catalogService.getSolution(theSolutionId, new ControllerContext());
155                         if(solution != null) {
156                                 response.setResponseBody(solution);
157                                 response.setResponseCode(String.valueOf(HttpServletResponse.SC_OK));
158                                 response.setResponseDetail(JSONTags.TAG_STATUS_SUCCESS);
159                                 response.setStatus(true);
160                                 theHttpResponse.setStatus(HttpServletResponse.SC_OK);
161                         }
162                 }
163                 catch (Exception e) {
164                         response.setResponseCode(String.valueOf(HttpServletResponse.SC_BAD_REQUEST));
165                         response.setResponseDetail(JSONTags.TAG_STATUS_FAILURE);
166                         response.setStatus(false);
167                         theHttpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
168                         log.error(EELFLoggerDelegate.errorLogger, "An error occurred fetching solution " + theSolutionId, e);
169                 }
170                 return response;
171         }
172
173
174         
175         /**
176          * @param request
177          *            HttpServletRequest
178          * @param response
179          *                      HttpServletResponse
180          * @return List of Published ML Solutions in JSON format.
181          */
182         @CrossOrigin
183         @PreAuthorize("hasAuthority('CATALOG_ACCESS')")
184         @ApiOperation(value = "Invoked by Peer Acumos to get a list of Solution Revision from the Catalog of the local Acumos Instance .", response = MLPSolutionRevision.class, responseContainer = "List")
185         @RequestMapping(value = {APINames.PEER_SOLUTION_REVISIONS}, method = RequestMethod.GET, produces = APPLICATION_JSON)
186         @ResponseBody
187         public JsonResponse<List<MLPSolutionRevision>> getSolutionRevisions(
188                         HttpServletResponse theHttpResponse,
189                         @PathVariable("solutionId") String theSolutionId) {
190                 JsonResponse<List<MLPSolutionRevision>> response = null;
191                 List<MLPSolutionRevision> solutionRevisions= null;
192                 log.debug(EELFLoggerDelegate.debugLogger, APINames.PEER_SOLUTION_REVISIONS);
193                 try {
194                         response = new JsonResponse<List<MLPSolutionRevision>>();
195                         solutionRevisions = catalogService.getSolutionRevisions(theSolutionId, new ControllerContext());
196                         if(solutionRevisions != null) {
197                                 response.setResponseBody(solutionRevisions);
198                                 response.setResponseCode(String.valueOf(HttpServletResponse.SC_OK));
199                                 response.setResponseDetail(JSONTags.TAG_STATUS_SUCCESS);
200                                 response.setStatus(true);
201                                 theHttpResponse.setStatus(HttpServletResponse.SC_OK);
202                                 log.debug(EELFLoggerDelegate.debugLogger, "getSolutionsRevisions: size is {} ", solutionRevisions.size());
203                         }
204                 }
205                 catch (Exception e) {
206                         response.setResponseCode(String.valueOf(HttpServletResponse.SC_BAD_REQUEST));
207                         response.setResponseDetail(JSONTags.TAG_STATUS_FAILURE);
208                         response.setStatus(false);
209                         theHttpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
210                         log.error(EELFLoggerDelegate.errorLogger, "Exception Occurred Fetching Solution Revisions", e);
211                 }
212                 return response;
213         }
214
215  /**
216          * @param request
217          *            HttpServletRequest
218          * @param response
219          *                      HttpServletResponse
220          * @return List of Published ML Solutions in JSON format.
221          */
222         @CrossOrigin
223         @PreAuthorize("hasAuthority('CATALOG_ACCESS')")
224         @ApiOperation(value = "Invoked by Peer Acumos to get Solution Revision details from the Catalog of the local Acumos Instance .", response = MLPSolutionRevision.class)
225         @RequestMapping(value = {APINames.PEER_SOLUTION_REVISION_DETAILS}, method = RequestMethod.GET, produces = APPLICATION_JSON)
226         @ResponseBody
227         public JsonResponse<MLPSolutionRevision> getSolutionRevisionDetails(
228                         HttpServletResponse theHttpResponse,
229                         @PathVariable("solutionId") String theSolutionId,
230                         @PathVariable("revisionId") String theRevisionId) {
231                 JsonResponse<MLPSolutionRevision> response = null;
232                 MLPSolutionRevision solutionRevision= null;
233                 log.debug(EELFLoggerDelegate.debugLogger, APINames.PEER_SOLUTION_REVISION_DETAILS);
234                 try {
235                         response = new JsonResponse<MLPSolutionRevision>();
236                         solutionRevision = catalogService.getSolutionRevision(theSolutionId, theRevisionId, new ControllerContext());
237                         if(solutionRevision != null) {
238                                 response.setResponseBody(solutionRevision);
239                                 response.setResponseCode(String.valueOf(HttpServletResponse.SC_OK));
240                                 response.setResponseDetail(JSONTags.TAG_STATUS_SUCCESS);
241                                 response.setStatus(true);
242                                 theHttpResponse.setStatus(HttpServletResponse.SC_OK);
243                         }
244                 }
245                 catch (Exception e) {
246                         response.setResponseCode(String.valueOf(HttpServletResponse.SC_BAD_REQUEST));
247                         response.setResponseDetail(JSONTags.TAG_STATUS_FAILURE);
248                         response.setStatus(false);
249                         theHttpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
250                         log.error(EELFLoggerDelegate.errorLogger, "Exception Occurred Fetching Solution Revision", e);
251                 }
252                 return response;
253         }
254         
255         /**
256          * @param request
257          *            HttpServletRequest
258          * @param response
259          *                      HttpServletResponse
260          * @return List of Published ML Solutions in JSON format.
261          */
262         @CrossOrigin
263         @PreAuthorize("hasAuthority('CATALOG_ACCESS')")
264         @ApiOperation(value = "Invoked by Peer Acumos to get a list of Solution Revision Artifacts from the Catalog of the local Acumos Instance .", response = MLPArtifact.class, responseContainer = "List")
265         @RequestMapping(value = {APINames.PEER_SOLUTION_REVISION_ARTIFACTS}, method = RequestMethod.GET, produces = APPLICATION_JSON)
266         @ResponseBody
267         public JsonResponse<List<MLPArtifact>> getSolutionRevisionArtifacts (
268                         HttpServletRequest theHttpRequest,
269                         HttpServletResponse theHttpResponse,
270                         @PathVariable("solutionId") String theSolutionId,
271                         @PathVariable("revisionId") String theRevisionId) {
272                 JsonResponse<List<MLPArtifact>> response = null;
273                 List<MLPArtifact> solutionRevisionArtifacts= null;
274                 log.debug(EELFLoggerDelegate.debugLogger, APINames.PEER_SOLUTION_REVISION_ARTIFACTS + ":" + theSolutionId + ":" + theRevisionId);
275                 try {
276                         response = new JsonResponse<List<MLPArtifact>>();
277                         solutionRevisionArtifacts = catalogService.getSolutionRevisionArtifacts(theSolutionId, theRevisionId, new ControllerContext());
278                         if(solutionRevisionArtifacts != null) {
279                                 //re-encode the artifact uri
280                                 {
281                       UriComponentsBuilder uriBuilder = 
282                                                 UriComponentsBuilder.fromHttpUrl(theHttpRequest.getRequestURL().toString());
283
284                                         for (MLPArtifact artifact: solutionRevisionArtifacts) {
285                                                 artifact.setUri(uriBuilder.replacePath("/artifacts/" + artifact.getArtifactId() + "/download")
286                                                                                                                                                         .toUriString());
287                                         }
288                                 }
289
290                                 response.setResponseBody(solutionRevisionArtifacts);
291                                 response.setResponseCode(String.valueOf(HttpServletResponse.SC_OK));
292                                 response.setResponseDetail(JSONTags.TAG_STATUS_SUCCESS);
293                                 response.setStatus(true);
294                                 theHttpResponse.setStatus(HttpServletResponse.SC_OK);
295                                 log.debug(EELFLoggerDelegate.debugLogger, "getSolutionRevisionArtifacts: size is {} ", solutionRevisionArtifacts.size());
296                         }
297                 }
298                 catch (Exception e) {
299                         response.setResponseCode(String.valueOf(HttpServletResponse.SC_BAD_REQUEST));
300                         response.setResponseDetail(JSONTags.TAG_STATUS_FAILURE);
301                         response.setStatus(false);
302                         theHttpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
303                         log.error(EELFLoggerDelegate.errorLogger, "Exception Occurred Fetching Solution Revisions Artifacts for Market Place Catalog", e);
304                 }
305                 return response;
306         }
307         
308         /**
309          * @param request
310          *            HttpServletRequest
311          * @param response
312          *                      HttpServletResponse
313          * @return Archive file of the Artifact for the Solution.
314          */
315         @CrossOrigin
316         @PreAuthorize("hasAuthority('CATALOG_ACCESS')")
317         @ApiOperation(value = "API to download the Machine Learning Artifact of the Machine Learning Solution", response = InputStreamResource.class, code = 200)
318         @RequestMapping(value = {APINames.PEER_ARTIFACT_DOWNLOAD}, method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
319         @ResponseBody
320         public InputStreamResource downloadSolutionArtifact(
321                         HttpServletRequest theHttpRequest,
322                         HttpServletResponse theHttpResponse,
323                         @PathVariable("artifactId") String theArtifactId) {
324                 InputStreamResource inputStreamResource = null;
325                 try {
326                         inputStreamResource = catalogService.getSolutionRevisionArtifactContent(theArtifactId, new ControllerContext());
327                         //TODO : Need to Implement a logic to download a Artifact or Docker Image from Nexus
328                         theHttpResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
329                         theHttpResponse.setHeader("Pragma", "no-cache");
330                         theHttpResponse.setHeader("Expires", "0");
331                         theHttpResponse.setStatus(HttpServletResponse.SC_OK);
332                 }
333                 catch (Exception e) {
334                         theHttpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
335                         log.error(EELFLoggerDelegate.errorLogger, "Exception Occurred downloading a artifact for a Solution in Market Place Catalog", e);
336                 }
337                 return inputStreamResource;
338         }
339
340         /**
341          */
342         protected class ControllerContext implements ServiceContext {
343
344                 public Peer getPeer() {
345                         return (Peer)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
346                 }
347         }
348 }
349