Search in sources :

Example 1 with ModelLink

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

the class ModelRepository method doGetLinksInSession.

private Set<ModelLink> doGetLinksInSession(ModelId modelID, Session session) throws RepositoryException {
    ObjectMapper objectMapper = ObjectMapperFactory.getInstance();
    Node fileNode = getFileNode(modelID, session);
    if (fileNode.hasProperty(VORTO_LINKS)) {
        return getVortoLinksPropertyValues(fileNode.getProperty(VORTO_LINKS)).stream().map(value -> deserializeLinkDto(objectMapper, value)).collect(Collectors.toSet());
    }
    return Collections.emptySet();
}
Also used : DependencyManager(org.eclipse.vorto.repository.core.impl.utils.DependencyManager) java.util(java.util) EventType(org.eclipse.vorto.repository.core.events.EventType) javax.jcr.query(javax.jcr.query) AppEvent(org.eclipse.vorto.repository.core.events.AppEvent) Function(java.util.function.Function) ModelLink(org.eclipse.vorto.repository.web.api.v1.dto.ModelLink) Model(org.eclipse.vorto.core.api.model.model.Model) Logger(org.apache.log4j.Logger) Lists(com.google.common.collect.Lists) ObjectMapperFactory(org.eclipse.vorto.plugin.generator.adapter.ObjectMapperFactory) ByteArrayInputStream(java.io.ByteArrayInputStream) IModelWorkspace(org.eclipse.vorto.utilities.reader.IModelWorkspace) ApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher) org.eclipse.vorto.repository.core(org.eclipse.vorto.repository.core) ModelState(org.eclipse.vorto.repository.workflow.ModelState) ModelParserFactory(org.eclipse.vorto.repository.core.impl.parser.ModelParserFactory) Attachment(org.eclipse.vorto.repository.core.Attachment) PrivilegeService(org.eclipse.vorto.repository.services.PrivilegeService) ApplicationEventPublisherAware(org.springframework.context.ApplicationEventPublisherAware) ModelSearchUtil(org.eclipse.vorto.repository.core.impl.utils.ModelSearchUtil) ModelIdHelper(org.eclipse.vorto.repository.core.impl.utils.ModelIdHelper) ModelReferencesHelper(org.eclipse.vorto.repository.core.impl.utils.ModelReferencesHelper) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) NotAuthorizedException(org.eclipse.vorto.repository.web.core.exceptions.NotAuthorizedException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) IOException(java.io.IOException) ModelId(org.eclipse.vorto.model.ModelId) ValidationException(org.eclipse.vorto.repository.core.impl.validation.ValidationException) Namespace(org.eclipse.vorto.repository.domain.Namespace) Collectors(java.util.stream.Collectors) ModelType(org.eclipse.vorto.model.ModelType) NamespaceService(org.eclipse.vorto.repository.services.NamespaceService) IOUtils(org.apache.commons.io.IOUtils) ChangeSet(org.eclipse.vorto.model.refactor.ChangeSet) RefactoringTask(org.eclipse.vorto.model.refactor.RefactoringTask) AttachmentValidator(org.eclipse.vorto.repository.core.impl.validation.AttachmentValidator) ModelWorkspaceReader(org.eclipse.vorto.utilities.reader.ModelWorkspaceReader) NewNamespacesNotSupersetException(org.eclipse.vorto.repository.tenant.NewNamespacesNotSupersetException) ModelUtils(org.eclipse.vorto.repository.utils.ModelUtils) IModelParser(org.eclipse.vorto.repository.core.impl.parser.IModelParser) javax.jcr(javax.jcr) InputStream(java.io.InputStream) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)

Example 2 with ModelLink

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

the class ModelRepositoryControllerTest method verifyFullModelPayloadForUI.

/**
 * This test performs the following:
 * <ol>
 *   <li>
 *     Creates the {@literal com.test} namespace with a sysadmin user, to hold the models.
 *   </li>
 *   <li>
 *     Adds a non-sysadmin user with {@literal model_creator} role to the {@literal com.test}
 *     namespace.
 *   </li>
 *   <li>
 *     Creates a "Zone" datatype model from the corresponding file resource.
 *   </li>
 *   <li>
 *     Creates a "Lamp" functionblock model from the corresponding file resource.
 *   </li>
 *   <li>
 *     Creates an "Address" functionblock model from the corresponding file resource.
 *   </li>
 *   <li>
 *     Creates a "StreetLamp" model from the corresponding file resource, using the above
 *     functionblocks as dependencies.
 *   </li>
 *   <li>
 *     Adds an attachment to the "StreetLamp" model.
 *   </li>
 *   <li>
 *     Adds a link to the "StreetLamp" model.
 *   </li>
 *   <li>
 *     Adds a mapping to the "StreetLamp" model.
 *   </li>
 *   <li>
 *     Loads the "StreetLamp" model with the REST call used by the UI, and verifies / validates:
 *     <ul>
 *       <li>
 *         Basic {@link org.eclipse.vorto.repository.core.ModelInfo} properties.
 *       </li>
 *       <li>
 *         The Base64-encoded model syntax
 *         (see {@link ModelFullDetailsDTO#getEncodedModelSyntax()})
 *       </li>
 *       <li>
 *         Mapping (see {@link ModelFullDetailsDTO#getMappings()}).
 *       </li>
 *       <li>
 *         Attachment (see {@link ModelFullDetailsDTO#getAttachments()}
 *       </li>
 *       <li>
 *         Link (see {@link ModelFullDetailsDTO#getLinks()}
 *       </li>
 *       <li>
 *         References (see {@link ModelFullDetailsDTO#getReferences()}
 *       </li>
 *       <li>
 *         "Referenced by" (see {@link ModelFullDetailsDTO#getReferencedBy()})
 *       </li>
 *       <li>
 *         Policies (see {@link ModelFullDetailsDTO#getPolicies()} and
 *         {@link ModelFullDetailsDTO#getBestPolicy()} for the creating user, and conversely, for
 *         an extraneous user with no access.
 *       </li>
 *       <li>
 *         Workflow actions (see {@link ModelFullDetailsDTO#getActions()} for the creating user,
 *         and conversely, for an extraneous user with no access.
 *       </li>
 *     </ul>
 *   </li>
 *   <li>
 *     Loads the "Lamp" functionblock model with the REST call used by the UI, and verifies the
 *     "referenced by" node (see {@link ModelFullDetailsDTO#getReferencedBy()}.
 *   </li>
 *   <li>
 *     Finally, cleans up and deletes all 4 models, then the namespace.
 *   </li>
 * </ol>
 *
 * @throws Exception
 */
@Test
public void verifyFullModelPayloadForUI() throws Exception {
    // required for some extra properties in DTOs not annotated with Jackson polymorphism
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // model names, id strings and file names
    String namespace = "com.test";
    String version = "1.0.0";
    String idFormat = "%s.%s:%s";
    String zoneModelName = "Zone";
    String zoneModelID = String.format(idFormat, namespace, zoneModelName, version);
    String zoneFileName = zoneModelName.concat(".type");
    String lampModelName = "Lamp";
    String lampModelID = String.format(idFormat, namespace, lampModelName, version);
    String lampFileName = lampModelName.concat(".fbmodel");
    String addressModelName = "Address";
    String addressModelID = String.format(idFormat, namespace, addressModelName, version);
    String addressFileName = addressModelName.concat(".fbmodel");
    String streetLampModelName = "StreetLamp";
    String streetLampModelID = String.format(idFormat, namespace, streetLampModelName, version);
    String streetLampFileName = streetLampModelName.concat(".infomodel");
    String streetLampAttachmentFileName = "StreetLampAttachment.json";
    String streetLampLinkURL = "https://vorto.eclipse.org/";
    String streetLampLinkName = "Vorto";
    // creates the namespace as sysadmin
    createNamespaceSuccessfully(namespace, userSysadmin);
    // creates the collaborator payload to add userModelCreator to the namespace
    Collaborator userModelCreatorCollaborator = new Collaborator();
    userModelCreatorCollaborator.setAuthenticationProviderId(GITHUB);
    userModelCreatorCollaborator.setRoles(Arrays.asList("model_viewer", "model_creator"));
    userModelCreatorCollaborator.setTechnicalUser(false);
    userModelCreatorCollaborator.setUserId(USER_MODEL_CREATOR_NAME);
    // allows creator rights to userCreator on namespace
    repositoryServer.perform(put(String.format("/rest/namespaces/%s/users", namespace)).with(userSysadmin).contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(userModelCreatorCollaborator))).andExpect(status().isOk());
    // creates the Zone model
    createModel(userModelCreator, zoneFileName, zoneModelID);
    // creates the Lamp model
    createModel(userModelCreator, lampFileName, lampModelID);
    // creates the Address model
    createModel(userModelCreator, addressFileName, addressModelID);
    // creates the StreetLamp model
    createModel(userModelCreator, streetLampFileName, streetLampModelID);
    // adds an attachment to the StreetLamp model (still requires sysadmin for this)
    addAttachment(streetLampModelID, userSysadmin, streetLampAttachmentFileName, MediaType.APPLICATION_JSON).andExpect(status().isOk()).andExpect(content().json(objectMapper.writeValueAsString(AttachResult.success(ModelId.fromPrettyFormat(streetLampModelID), streetLampAttachmentFileName))));
    // adds a link to the StreetLamp model
    ModelLink link = new ModelLink(streetLampLinkURL, streetLampLinkName);
    addLink(streetLampModelID, userModelCreator, link);
    // saves a minimal mapping specification for the street lamp model
    Infomodel streetLampInfomodel = new Infomodel(ModelId.fromPrettyFormat(streetLampModelID));
    streetLampInfomodel.setTargetPlatformKey("myTargetPlatform");
    MappingSpecification mapping = new MappingSpecification(streetLampInfomodel);
    repositoryServer.perform(put(String.format("/rest/mappings/specifications/%s", streetLampModelID)).contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(mapping)).with(userModelCreator)).andExpect(status().isOk());
    // expected ID of the payload mapping model
    String mappingId = String.format("%s.%s:%sPayloadMapping:%s", // root namespace
    namespace, // virtual namespace for mapping
    streetLampModelName.toLowerCase(), // mapping name part 1 matching root model
    streetLampModelName, // root model version
    version);
    // fetches the full model for the UI
    repositoryServer.perform(get(String.format("/rest/models/ui/%s", streetLampModelID)).with(userModelCreator)).andExpect(status().isOk()).andDo(mvcResult -> {
        ModelFullDetailsDTO output = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ModelFullDetailsDTO.class);
        LOGGER.info(new StringBuilder("\nReceived response body:\n\n").append(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(output)).toString());
    }).andExpect(jsonPath("$.modelInfo").exists()).andExpect(jsonPath("$.modelInfo.id.name").value(streetLampModelName)).andExpect(jsonPath("$.modelInfo.id.namespace").value(namespace)).andExpect(jsonPath("$.modelInfo.type").value("InformationModel")).andExpect(jsonPath("$.modelInfo.author").value(USER_MODEL_CREATOR_NAME)).andExpect(jsonPath("$.mappings").isNotEmpty()).andExpect(jsonPath("$.mappings[0].id").value(mappingId)).andExpect(jsonPath("$.references", hasSize(2))).andExpect(jsonPath("$.referencedBy", hasSize(1))).andExpect(jsonPath("$.referencedBy[0].id").value(mappingId)).andExpect(jsonPath("$.attachments").exists()).andExpect(jsonPath("$.attachments[0].filename").value(streetLampAttachmentFileName)).andExpect(jsonPath("$.attachments[0].modelId.name").value(streetLampModelName)).andExpect(jsonPath("$.links").exists()).andExpect(jsonPath("$.links[0].url").value(equalTo(link.getUrl()))).andExpect(jsonPath("$.links[0].displayText").value(equalTo(link.getDisplayText()))).andExpect(jsonPath("$.actions").exists()).andExpect(jsonPath("$.actions").isEmpty()).andExpect(jsonPath("$.policies", hasSize(2))).andExpect(jsonPath("$.bestPolicy").exists()).andExpect(jsonPath("$.bestPolicy.principalId").value("model_creator")).andExpect(jsonPath("$.bestPolicy.permission").value(Permission.FULL_ACCESS.toString())).andExpect(jsonPath("$.encodedModelSyntax").value(Base64.getEncoder().encodeToString(createContentAsString(streetLampFileName).getBytes())));
    // cleanup: deletes models in reverse order of creation, then namespace
    repositoryServer.perform(delete(String.format("/rest/models/%s", mappingId)).with(userModelCreator)).andExpect(status().isOk());
    repositoryServer.perform(delete(String.format("/rest/models/%s", streetLampModelID)).with(userModelCreator)).andExpect(status().isOk());
    repositoryServer.perform(delete(String.format("/rest/models/%s", lampModelID)).with(userModelCreator)).andExpect(status().isOk());
    repositoryServer.perform(delete(String.format("/rest/models/%s", addressModelID)).with(userModelCreator)).andExpect(status().isOk());
    repositoryServer.perform(delete(String.format("/rest/models/%s", zoneModelID)).with(userModelCreator)).andExpect(status().isOk());
    repositoryServer.perform(delete(String.format("/rest/namespaces/%s", namespace)).with(userSysadmin)).andExpect(status().isNoContent());
    // removes test-specific configuration
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
}
Also used : Arrays(java.util.Arrays) MockMvcResultMatchers.jsonPath(org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath) MappingSpecification(org.eclipse.vorto.mapping.engine.model.spec.MappingSpecification) CoreMatchers.equalTo(org.hamcrest.CoreMatchers.equalTo) ModelFullDetailsDTO(org.eclipse.vorto.repository.web.api.v1.dto.ModelFullDetailsDTO) Autowired(org.springframework.beans.factory.annotation.Autowired) Infomodel(org.eclipse.vorto.model.Infomodel) MockMvcResultMatchers.content(org.springframework.test.web.servlet.result.MockMvcResultMatchers.content) DeserializationFeature(com.fasterxml.jackson.databind.DeserializationFeature) ModelLink(org.eclipse.vorto.repository.web.api.v1.dto.ModelLink) MockMvcRequestBuilders.delete(org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete) Logger(org.apache.log4j.Logger) MockMvcResultMatchers.status(org.springframework.test.web.servlet.result.MockMvcResultMatchers.status) MockMvcRequestBuilders.post(org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post) Matchers.hasSize(org.hamcrest.Matchers.hasSize) Collaborator(org.eclipse.vorto.repository.web.api.v1.dto.Collaborator) MockMvcRequestBuilders.put(org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put) MediaType(org.springframework.http.MediaType) Test(org.junit.Test) ModelId(org.eclipse.vorto.model.ModelId) Sets(com.google.common.collect.Sets) ModelType(org.eclipse.vorto.model.ModelType) Base64(java.util.Base64) AttachmentValidator(org.eclipse.vorto.repository.core.impl.validation.AttachmentValidator) MockMvcRequestBuilders.get(org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get) Permission(org.eclipse.vorto.repository.core.PolicyEntry.Permission) AttachResult(org.eclipse.vorto.repository.web.api.v1.dto.AttachResult) ModelFullDetailsDTO(org.eclipse.vorto.repository.web.api.v1.dto.ModelFullDetailsDTO) Collaborator(org.eclipse.vorto.repository.web.api.v1.dto.Collaborator) MappingSpecification(org.eclipse.vorto.mapping.engine.model.spec.MappingSpecification) ModelLink(org.eclipse.vorto.repository.web.api.v1.dto.ModelLink) Infomodel(org.eclipse.vorto.model.Infomodel) Test(org.junit.Test)

Example 3 with ModelLink

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

the class AttachmentsControllerIntegrationTest method testAttachingLink.

@Test
public void testAttachingLink() throws Exception {
    List<ModelLink> expectedResult = new ArrayList<>();
    ModelLink url = new ModelLink("https://vorto.eclipse.org", "A link");
    ModelLink url2 = new ModelLink("https://vorto-dev.eclipse.org", "Another link");
    setPublic(testModel.prettyName);
    addLink(testModel.prettyName, userModelCreator, url).andExpect(status().isOk());
    expectedResult.add(url);
    repositoryServer.perform(get("/api/v1/attachments/" + testModel.prettyName + "/links").with(userModelViewer)).andExpect(content().json(gson.toJson(expectedResult))).andExpect(status().isOk());
    addLink(testModel.prettyName, userModelCreator, url2).andExpect(status().isOk());
    expectedResult.add(url2);
    repositoryServer.perform(get("/api/v1/attachments/" + testModel.prettyName + "/links").with(userModelViewer)).andExpect(content().json(gson.toJson(expectedResult))).andExpect(status().isOk());
    deleteLink(testModel.prettyName, userModelCreator, url).andExpect(status().isOk());
    expectedResult.remove(url);
    repositoryServer.perform(get("/api/v1/attachments/" + testModel.prettyName + "/links").with(userModelViewer)).andExpect(content().json(gson.toJson(expectedResult))).andExpect(status().isOk());
    deleteLink(testModel.prettyName, userModelCreator, url2).andExpect(status().isOk());
    expectedResult.remove(url2);
    repositoryServer.perform(get("/api/v1/attachments/" + testModel.prettyName + "/links").with(userModelViewer)).andExpect(content().json(gson.toJson(expectedResult))).andExpect(status().isOk());
    deleteLink(testModel.prettyName, userSysadmin, url2).andExpect(status().isOk());
    addLink("unknown:unknown:1.0.0", userSysadmin, url).andExpect(status().isNotFound());
    addLink(testModel.prettyName, userModelViewer, url).andExpect(status().isForbidden());
    deleteLink(testModel.prettyName, userModelViewer, url2).andExpect(status().isForbidden());
}
Also used : ModelLink(org.eclipse.vorto.repository.web.api.v1.dto.ModelLink) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Example 4 with ModelLink

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

the class IntegrationTestBase method addLink.

protected ResultActions addLink(String modelId, SecurityMockMvcRequestPostProcessors.UserRequestPostProcessor user, ModelLink url) throws Exception {
    MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.put("/api/v1/attachments/" + modelId + "/links");
    builder.content(ObjectMapperFactory.getInstance().writeValueAsString(url));
    return repositoryServer.perform(builder.with(request -> {
        request.setMethod("PUT");
        return request;
    }).contentType(MediaType.APPLICATION_JSON).with(user));
}
Also used : OperationResult(org.eclipse.vorto.repository.web.api.v1.dto.OperationResult) Autowired(org.springframework.beans.factory.annotation.Autowired) ActiveProfiles(org.springframework.test.context.ActiveProfiles) GsonBuilder(com.google.gson.GsonBuilder) MockHttpServletRequestBuilder(org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder) ResultActions(org.springframework.test.web.servlet.ResultActions) ObjectMapperFactory(org.eclipse.vorto.plugin.generator.adapter.ObjectMapperFactory) Gson(com.google.gson.Gson) VortoRepository(org.eclipse.vorto.repository.web.VortoRepository) SpringRunner(org.springframework.test.context.junit4.SpringRunner) TypeReference(com.fasterxml.jackson.core.type.TypeReference) LocalServerPort(org.springframework.boot.context.embedded.LocalServerPort) MediaType(org.springframework.http.MediaType) UserService(org.eclipse.vorto.repository.services.UserService) WebApplicationContext(org.springframework.web.context.WebApplicationContext) TestPropertySource(org.springframework.test.context.TestPropertySource) ModelId(org.eclipse.vorto.model.ModelId) Sql(org.springframework.test.context.jdbc.Sql) Sets(com.google.common.collect.Sets) MockMultipartFile(org.springframework.mock.web.MockMultipartFile) GrantedAuthority(org.springframework.security.core.GrantedAuthority) Configuration(org.springframework.context.annotation.Configuration) IOUtils(org.apache.commons.io.IOUtils) SecurityMockMvcConfigurers.springSecurity(org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) SecurityMockMvcRequestPostProcessors(org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors) java.util(java.util) BeforeClass(org.junit.BeforeClass) RunWith(org.junit.runner.RunWith) ClassPathResource(org.springframework.core.io.ClassPathResource) SimpleGrantedAuthority(org.springframework.security.core.authority.SimpleGrantedAuthority) MockMvcResultMatchers.content(org.springframework.test.web.servlet.result.MockMvcResultMatchers.content) ModelLink(org.eclipse.vorto.repository.web.api.v1.dto.ModelLink) Value(org.springframework.beans.factory.annotation.Value) MockMvc(org.springframework.test.web.servlet.MockMvc) MockMvcResultMatchers.status(org.springframework.test.web.servlet.result.MockMvcResultMatchers.status) ConfigFileApplicationContextInitializer(org.springframework.boot.test.context.ConfigFileApplicationContextInitializer) PropertySourcesPlaceholderConfigurer(org.springframework.context.support.PropertySourcesPlaceholderConfigurer) MockMvcBuilders(org.springframework.test.web.servlet.setup.MockMvcBuilders) INotificationService(org.eclipse.vorto.repository.notification.INotificationService) Collaborator(org.eclipse.vorto.repository.web.api.v1.dto.Collaborator) Before(org.junit.Before) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Assert.assertTrue(org.junit.Assert.assertTrue) PolicyEntry(org.eclipse.vorto.repository.core.PolicyEntry) Profile(org.springframework.context.annotation.Profile) MockMvcRequestBuilders(org.springframework.test.web.servlet.request.MockMvcRequestBuilders) SecurityMockMvcRequestPostProcessors.user(org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user) ModelType(org.eclipse.vorto.model.ModelType) IModelPolicyManager(org.eclipse.vorto.repository.core.IModelPolicyManager) UserRepository(org.eclipse.vorto.repository.repositories.UserRepository) ContextConfiguration(org.springframework.test.context.ContextConfiguration) MockMultipartHttpServletRequestBuilder(org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder) Bean(org.springframework.context.annotation.Bean) Assert.assertEquals(org.junit.Assert.assertEquals) MockHttpServletRequestBuilder(org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder)

Example 5 with ModelLink

use of org.eclipse.vorto.repository.web.api.v1.dto.ModelLink 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

ModelLink (org.eclipse.vorto.repository.web.api.v1.dto.ModelLink)6 ModelId (org.eclipse.vorto.model.ModelId)5 ModelType (org.eclipse.vorto.model.ModelType)5 IOUtils (org.apache.commons.io.IOUtils)4 Autowired (org.springframework.beans.factory.annotation.Autowired)4 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)3 Sets (com.google.common.collect.Sets)3 java.util (java.util)3 Logger (org.apache.log4j.Logger)3 IModelPolicyManager (org.eclipse.vorto.repository.core.IModelPolicyManager)3 TypeReference (com.fasterxml.jackson.core.type.TypeReference)2 Lists (com.google.common.collect.Lists)2 Gson (com.google.gson.Gson)2 GsonBuilder (com.google.gson.GsonBuilder)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 IOException (java.io.IOException)2 Collectors (java.util.stream.Collectors)2 ObjectMapperFactory (org.eclipse.vorto.plugin.generator.adapter.ObjectMapperFactory)2 PolicyEntry (org.eclipse.vorto.repository.core.PolicyEntry)2 AttachmentValidator (org.eclipse.vorto.repository.core.impl.validation.AttachmentValidator)2