Search in sources :

Example 1 with ModelMinimalInfoDTO

use of org.eclipse.vorto.repository.web.api.v1.dto.ModelMinimalInfoDTO in project vorto by eclipse.

the class ModelRepositoryController method getModelForUI.

/**
 * Fetches all data required to populate the returned {@link ModelFullDetailsDTO} (see class docs
 * for details), in addition the model's "file" contents as file added to the response.<br/>
 * Following error cases apply:
 * <ul>
 *   <li>
 *     If {@link ModelId#fromPrettyFormat(String)} fails throwing {@link IllegalArgumentException},
 *     returns {@code null} with status {@link HttpStatus#NOT_FOUND}.
 *   </li>
 *   <li>
 *     If {@link ModelRepositoryController#getWorkspaceId(String)} fails throwing
 *     {@link FatalModelRepositoryException}, returns {@code null} with status
 *     {@link HttpStatus#NOT_FOUND}.
 *   </li>
 *   <li>
 *     If any operation such as:
 *     <ul>
 *       <li>
 *         {@link IModelRepository#getByIdWithPlatformMappings(ModelId)}
 *       </li>
 *       <li>
 *         {@link IModelRepository#getAttachments(ModelId)}
 *       </li>
 *       <li>
 *         {@link IModelPolicyManager#getPolicyEntries(ModelId)}
 *       </li>
 *     </ul>
 *     ... fails throwing {@link NotAuthorizedException}, returns {@code null} with status
 *     {@link HttpStatus#FORBIDDEN};
 *   </li>
 * </ul>
 *
 * @param modelId
 * @return
 */
@GetMapping("/ui/{modelId:.+}")
public ResponseEntity<ModelFullDetailsDTO> getModelForUI(@PathVariable String modelId, final HttpServletResponse response) {
    try {
        // resolve user
        Authentication user = SecurityContextHolder.getContext().getAuthentication();
        // resolve model ID
        ModelId modelID = ModelId.fromPrettyFormat(modelId);
        // resolve ModeShape workspace ID
        String workspaceId = getWorkspaceId(modelId);
        // fetches model info
        ModelInfo modelInfo = getModelRepository(modelID).getByIdWithPlatformMappings(modelID);
        if (Objects.isNull(modelInfo)) {
            LOGGER.warn(String.format("Model resource with id [%s] not found. ", modelId));
            return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
        }
        // starts spawning threads to retrieve models etc.
        final ExecutorService executor = Executors.newCachedThreadPool();
        // fetches mappings
        Collection<ModelMinimalInfoDTO> mappings = ConcurrentHashMap.newKeySet();
        modelInfo.getPlatformMappings().entrySet().stream().forEach(e -> {
            executor.submit(new AsyncModelMappingsFetcher(mappings, e).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()).with(getModelRepositoryFactory()));
        });
        // fetches references from model ids built with the root ModelInfo
        Collection<ModelMinimalInfoDTO> references = ConcurrentHashMap.newKeySet();
        modelInfo.getReferences().stream().forEach(id -> executor.submit(new AsyncModelReferenceFetcher(references, id).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()).with(getModelRepositoryFactory())));
        // fetches referenced by
        Collection<ModelMinimalInfoDTO> referencedBy = ConcurrentHashMap.newKeySet();
        modelInfo.getReferencedBy().stream().forEach(id -> executor.submit(new AsyncModelReferenceFetcher(referencedBy, id).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()).with(getModelRepositoryFactory())));
        // fetches attachments
        Collection<Attachment> attachments = ConcurrentHashMap.newKeySet();
        executor.submit(new AsyncModelAttachmentsFetcher(attachments, modelID, userRepositoryRoleService.isSysadmin(user.getName())).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()).with(getModelRepositoryFactory()));
        // fetches links
        Collection<ModelLink> links = ConcurrentHashMap.newKeySet();
        executor.submit(new AsyncModelLinksFetcher(modelID, links).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()).with(getModelRepositoryFactory()));
        // fetches available workflow actions
        Collection<String> actions = ConcurrentHashMap.newKeySet();
        executor.submit(new AsyncWorkflowActionsFetcher(workflowService, actions, modelID, UserContext.user(user, workspaceId)).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()));
        // fetches model syntax
        Future<String> encodedSyntaxFuture = executor.submit(new AsyncModelSyntaxFetcher(modelID, SecurityContextHolder.getContext(), RequestContextHolder.getRequestAttributes(), getModelRepositoryFactory()));
        // shuts down executor and waits for completion of tasks until configured timeout
        // also retrieves callable content
        executor.shutdown();
        // single-threaded calls
        // fetches policies in this thread
        Collection<PolicyEntry> policies = getPolicyManager(workspaceId).getPolicyEntries(modelID).stream().filter(p -> userHasPolicyEntry(p, user, workspaceId)).collect(Collectors.toList());
        // getting callables and setting executor timeout
        String encodedSyntax = null;
        try {
            // callable content
            encodedSyntax = encodedSyntaxFuture.get();
            // timeout
            if (!executor.awaitTermination(requestTimeoutInSeconds, TimeUnit.SECONDS)) {
                LOGGER.warn(String.format("Requesting UI data for model ID [%s] took over [%d] seconds and programmatically timed out.", modelID, requestTimeoutInSeconds));
                return new ResponseEntity<>(null, HttpStatus.GATEWAY_TIMEOUT);
            }
        } catch (InterruptedException ie) {
            LOGGER.error("Awaiting executor termination was interrupted.");
            return new ResponseEntity<>(null, HttpStatus.SERVICE_UNAVAILABLE);
        } catch (ExecutionException ee) {
            LOGGER.error("Failed to retrieve and encode model syntax asynchronously");
            return new ResponseEntity<>(null, HttpStatus.SERVICE_UNAVAILABLE);
        }
        // builds DTO
        ModelFullDetailsDTO dto = new ModelFullDetailsDTO().withModelInfo(modelInfo).withMappings(mappings).withReferences(references).withReferencedBy(referencedBy).withAttachments(attachments).withLinks(links).withActions(actions).withEncodedModelSyntax(encodedSyntax).withPolicies(policies);
        return new ResponseEntity<>(dto, HttpStatus.OK);
    }// could not resolve "pretty format" for given model ID
     catch (IllegalArgumentException iae) {
        LOGGER.warn(String.format("Could not resolve given model ID [%s]", modelId), iae);
        return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
    }// could not find namespace to resolve workspace ID from
     catch (FatalModelRepositoryException fmre) {
        LOGGER.warn(String.format("Could not resolve workspace ID from namespace inferred by model ID [%s]", modelId), fmre);
        return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
    } catch (NotAuthorizedException nae) {
        LOGGER.warn(String.format("Could not authorize fetching data from given model ID [%s] for calling user", modelId), nae);
        return new ResponseEntity<>(null, HttpStatus.FORBIDDEN);
    }
}
Also used : AsyncWorkflowActionsFetcher(org.eclipse.vorto.repository.web.core.async.AsyncWorkflowActionsFetcher) InfomodelTemplate(org.eclipse.vorto.repository.web.core.templates.InfomodelTemplate) RequestParam(org.springframework.web.bind.annotation.RequestParam) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize) ApiParam(io.swagger.annotations.ApiParam) Autowired(org.springframework.beans.factory.annotation.Autowired) ModelAlreadyExistsException(org.eclipse.vorto.repository.core.ModelAlreadyExistsException) ModelInfo(org.eclipse.vorto.repository.core.ModelInfo) RequestContextHolder(org.springframework.web.context.request.RequestContextHolder) Future(java.util.concurrent.Future) Map(java.util.Map) Diagnostic(org.eclipse.vorto.repository.core.Diagnostic) AsyncModelMappingsFetcher(org.eclipse.vorto.repository.web.core.async.AsyncModelMappingsFetcher) SecurityContextHolder(org.springframework.security.core.context.SecurityContextHolder) ModelParserFactory(org.eclipse.vorto.repository.core.impl.parser.ModelParserFactory) PostMapping(org.springframework.web.bind.annotation.PostMapping) AsyncModelLinksFetcher(org.eclipse.vorto.repository.web.core.async.AsyncModelLinksFetcher) NotAuthorizedException(org.eclipse.vorto.repository.web.core.exceptions.NotAuthorizedException) User(org.eclipse.vorto.repository.domain.User) Namespace(org.eclipse.vorto.repository.domain.Namespace) RestController(org.springframework.web.bind.annotation.RestController) Executors(java.util.concurrent.Executors) IOUtils(org.apache.commons.io.IOUtils) Permission(org.eclipse.vorto.repository.core.PolicyEntry.Permission) DefaultUserAccountService(org.eclipse.vorto.repository.account.impl.DefaultUserAccountService) ZipOutputStream(java.util.zip.ZipOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ModelFullDetailsDTO(org.eclipse.vorto.repository.web.api.v1.dto.ModelFullDetailsDTO) ControllerUtils(org.eclipse.vorto.repository.web.ControllerUtils) ModelLink(org.eclipse.vorto.repository.web.api.v1.dto.ModelLink) IModelRepository(org.eclipse.vorto.repository.core.IModelRepository) Value(org.springframework.beans.factory.annotation.Value) RequestBody(org.springframework.web.bind.annotation.RequestBody) FatalModelRepositoryException(org.eclipse.vorto.repository.core.FatalModelRepositoryException) IWorkflowService(org.eclipse.vorto.repository.workflow.IWorkflowService) Lists(com.google.common.collect.Lists) Attachment(org.eclipse.vorto.repository.core.Attachment) AsyncModelSyntaxFetcher(org.eclipse.vorto.repository.web.core.async.AsyncModelSyntaxFetcher) UserRepositoryRoleService(org.eclipse.vorto.repository.services.UserRepositoryRoleService) ModelProperty(org.eclipse.vorto.model.ModelProperty) ModelNotReleasedException(org.eclipse.vorto.repository.model.ModelNotReleasedException) GenericApplicationException(org.eclipse.vorto.repository.web.GenericApplicationException) IOException(java.io.IOException) IModelPolicyManager(org.eclipse.vorto.repository.core.IModelPolicyManager) NamespaceService(org.eclipse.vorto.repository.services.NamespaceService) ExecutionException(java.util.concurrent.ExecutionException) HttpStatus(org.springframework.http.HttpStatus) ApiResponse(io.swagger.annotations.ApiResponse) AttachmentValidator(org.eclipse.vorto.repository.core.impl.validation.AttachmentValidator) AttachResult(org.eclipse.vorto.repository.web.api.v1.dto.AttachResult) ModelTemplate(org.eclipse.vorto.repository.web.core.templates.ModelTemplate) PathVariable(org.springframework.web.bind.annotation.PathVariable) ValidationReport(org.eclipse.vorto.repository.importer.ValidationReport) DoesNotExistException(org.eclipse.vorto.repository.services.exceptions.DoesNotExistException) ApiOperation(io.swagger.annotations.ApiOperation) Logger(org.apache.log4j.Logger) AbstractRepositoryController(org.eclipse.vorto.repository.web.AbstractRepositoryController) ByteArrayInputStream(java.io.ByteArrayInputStream) PutMapping(org.springframework.web.bind.annotation.PutMapping) ModelMinimalInfoDTO(org.eclipse.vorto.repository.web.api.v1.dto.ModelMinimalInfoDTO) ZipEntry(java.util.zip.ZipEntry) DeleteMapping(org.springframework.web.bind.annotation.DeleteMapping) AsyncWorkflowActionsFetcher(org.eclipse.vorto.repository.web.core.async.AsyncWorkflowActionsFetcher) FileContent(org.eclipse.vorto.repository.core.FileContent) IDiagnostics(org.eclipse.vorto.repository.core.IDiagnostics) Collection(java.util.Collection) ModelValidationHelper(org.eclipse.vorto.repository.core.impl.utils.ModelValidationHelper) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) OperationForbiddenException(org.eclipse.vorto.repository.services.exceptions.OperationForbiddenException) Collectors(java.util.stream.Collectors) ModelId(org.eclipse.vorto.model.ModelId) Objects(java.util.Objects) List(java.util.List) Principal(java.security.Principal) Optional(java.util.Optional) WorkflowException(org.eclipse.vorto.repository.workflow.WorkflowException) Authentication(org.springframework.security.core.Authentication) IUserContext(org.eclipse.vorto.repository.core.IUserContext) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) HashMap(java.util.HashMap) ApiResponses(io.swagger.annotations.ApiResponses) AsyncModelAttachmentsFetcher(org.eclipse.vorto.repository.web.core.async.AsyncModelAttachmentsFetcher) Status(org.eclipse.vorto.repository.web.Status) GetMapping(org.springframework.web.bind.annotation.GetMapping) ExecutorService(java.util.concurrent.ExecutorService) ModelContent(org.eclipse.vorto.repository.web.core.dto.ModelContent) ModelNamespaceNotOfficialException(org.eclipse.vorto.repository.model.ModelNamespaceNotOfficialException) AsyncModelReferenceFetcher(org.eclipse.vorto.repository.web.core.async.AsyncModelReferenceFetcher) IBulkOperationsService(org.eclipse.vorto.repository.model.IBulkOperationsService) UserNamespaceRoleService(org.eclipse.vorto.repository.services.UserNamespaceRoleService) HttpServletResponse(javax.servlet.http.HttpServletResponse) PolicyEntry(org.eclipse.vorto.repository.core.PolicyEntry) ValidationException(org.eclipse.vorto.repository.core.impl.validation.ValidationException) ModelType(org.eclipse.vorto.model.ModelType) TimeUnit(java.util.concurrent.TimeUnit) ModelResource(org.eclipse.vorto.repository.core.ModelResource) PrincipalType(org.eclipse.vorto.repository.core.PolicyEntry.PrincipalType) MultipartFile(org.springframework.web.multipart.MultipartFile) ResponseEntity(org.springframework.http.ResponseEntity) UserContext(org.eclipse.vorto.repository.core.impl.UserContext) ModelInfo(org.eclipse.vorto.repository.core.ModelInfo) AsyncModelAttachmentsFetcher(org.eclipse.vorto.repository.web.core.async.AsyncModelAttachmentsFetcher) FatalModelRepositoryException(org.eclipse.vorto.repository.core.FatalModelRepositoryException) Attachment(org.eclipse.vorto.repository.core.Attachment) NotAuthorizedException(org.eclipse.vorto.repository.web.core.exceptions.NotAuthorizedException) PolicyEntry(org.eclipse.vorto.repository.core.PolicyEntry) AsyncModelMappingsFetcher(org.eclipse.vorto.repository.web.core.async.AsyncModelMappingsFetcher) ModelFullDetailsDTO(org.eclipse.vorto.repository.web.api.v1.dto.ModelFullDetailsDTO) ExecutionException(java.util.concurrent.ExecutionException) ModelId(org.eclipse.vorto.model.ModelId) AsyncModelReferenceFetcher(org.eclipse.vorto.repository.web.core.async.AsyncModelReferenceFetcher) AsyncModelLinksFetcher(org.eclipse.vorto.repository.web.core.async.AsyncModelLinksFetcher) ResponseEntity(org.springframework.http.ResponseEntity) ModelMinimalInfoDTO(org.eclipse.vorto.repository.web.api.v1.dto.ModelMinimalInfoDTO) ModelLink(org.eclipse.vorto.repository.web.api.v1.dto.ModelLink) Authentication(org.springframework.security.core.Authentication) AsyncModelSyntaxFetcher(org.eclipse.vorto.repository.web.core.async.AsyncModelSyntaxFetcher) ExecutorService(java.util.concurrent.ExecutorService) GetMapping(org.springframework.web.bind.annotation.GetMapping)

Aggregations

Lists (com.google.common.collect.Lists)1 ApiOperation (io.swagger.annotations.ApiOperation)1 ApiParam (io.swagger.annotations.ApiParam)1 ApiResponse (io.swagger.annotations.ApiResponse)1 ApiResponses (io.swagger.annotations.ApiResponses)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 Principal (java.security.Principal)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ExecutionException (java.util.concurrent.ExecutionException)1 ExecutorService (java.util.concurrent.ExecutorService)1 Executors (java.util.concurrent.Executors)1 Future (java.util.concurrent.Future)1