Skip to content

Commit

Permalink
Merge pull request #8093 from vaadin/cp/3.0
Browse files Browse the repository at this point in the history
3.0 cherry pick
  • Loading branch information
haijian-vaadin committed Apr 17, 2020
2 parents 03b4a1d + a80851a commit 30a303e
Show file tree
Hide file tree
Showing 27 changed files with 429 additions and 143 deletions.
8 changes: 6 additions & 2 deletions flow-server/pom.xml
Expand Up @@ -15,7 +15,6 @@
<properties>
<validation.api.version>2.0.1.Final</validation.api.version>
<jackson.version>2.10.2</jackson.version>
<jackson.databind.version>2.10.2</jackson.databind.version>
<spring.version>5.2.0.RELEASE</spring.version>
<spring.autoconfigure.version>2.2.0.RELEASE</spring.autoconfigure.version>
<javax.annotation.api.version>1.3.2</javax.annotation.api.version>
Expand Down Expand Up @@ -198,7 +197,12 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.databind.version}</version>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- Needed for security annotations -->
<dependency>
Expand Down
Expand Up @@ -39,18 +39,23 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jackson.JacksonProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand Down Expand Up @@ -126,12 +131,15 @@ public class VaadinConnectController {
* from
*/
public VaadinConnectController(
@Qualifier(VAADIN_ENDPOINT_MAPPER_BEAN_QUALIFIER) ObjectMapper vaadinEndpointMapper,
@Autowired(required = false) @Qualifier(VAADIN_ENDPOINT_MAPPER_BEAN_QUALIFIER)
ObjectMapper vaadinEndpointMapper,
VaadinConnectAccessChecker accessChecker,
EndpointNameChecker endpointNameChecker,
ExplicitNullableTypeChecker explicitNullableTypeChecker,
ApplicationContext context) {
this.vaadinEndpointMapper = vaadinEndpointMapper;
this.vaadinEndpointMapper = vaadinEndpointMapper != null
? vaadinEndpointMapper
: createVaadinConnectObjectMapper(context);
this.accessChecker = accessChecker;
this.explicitNullableTypeChecker = explicitNullableTypeChecker;

Expand All @@ -140,6 +148,18 @@ public VaadinConnectController(
name, endpointBean));
}

private ObjectMapper createVaadinConnectObjectMapper(ApplicationContext context) {
Jackson2ObjectMapperBuilder builder = context.getBean(Jackson2ObjectMapperBuilder.class);
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
JacksonProperties jacksonProperties = context
.getBean(JacksonProperties.class);
if (jacksonProperties.getVisibility().isEmpty()) {
objectMapper.setVisibility(PropertyAccessor.ALL,
JsonAutoDetect.Visibility.ANY);
}
return objectMapper;
}

private static Logger getLogger() {
return LoggerFactory.getLogger(VaadinConnectController.class);
}
Expand Down
Expand Up @@ -18,13 +18,7 @@

import java.lang.reflect.Method;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jackson.JacksonProperties;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
Expand All @@ -33,8 +27,6 @@

import com.vaadin.flow.server.connect.auth.VaadinConnectAccessChecker;

import static com.vaadin.flow.server.connect.VaadinConnectController.VAADIN_ENDPOINT_MAPPER_BEAN_QUALIFIER;

/**
* A configuration class for customizing the {@link VaadinConnectController}
* class.
Expand Down Expand Up @@ -142,24 +134,4 @@ public VaadinConnectAccessChecker accessChecker() {
public ExplicitNullableTypeChecker typeChecker() {
return new ExplicitNullableTypeChecker();
}

/**
* Registers a {@link ObjectMapper} bean instance.
*
* @param context
* Spring application context
* @return the object mapper for endpoint.
*/
@Bean
@Qualifier(VAADIN_ENDPOINT_MAPPER_BEAN_QUALIFIER)
public ObjectMapper vaadinEndpointMapper(ApplicationContext context) {
ObjectMapper objectMapper = new ObjectMapper();
JacksonProperties jacksonProperties = context
.getBean(JacksonProperties.class);
if (jacksonProperties.getVisibility().isEmpty()) {
objectMapper.setVisibility(PropertyAccessor.ALL,
JsonAutoDetect.Visibility.ANY);
}
return objectMapper;
}
}

This file was deleted.

Expand Up @@ -37,6 +37,7 @@
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import com.vaadin.flow.server.MockVaadinServletService;
import com.vaadin.flow.server.VaadinService;
Expand Down Expand Up @@ -586,7 +587,6 @@ public MyCustomException() {
}

@Test
@Ignore("requires mockito version with plugin for final classes")
public void should_Return500_When_MapperFailsToSerializeResponse()
throws Exception {
ObjectMapper mapperMock = mock(ObjectMapper.class);
Expand Down Expand Up @@ -629,7 +629,6 @@ public void should_Return500_When_MapperFailsToSerializeResponse()
}

@Test
@Ignore("requires mockito version with plugin for final classes")
public void should_ThrowException_When_MapperFailsToSerializeEverything()
throws Exception {
ObjectMapper mapperMock = mock(ObjectMapper.class);
Expand Down Expand Up @@ -791,11 +790,19 @@ public void should_UseCustomEndpointName_When_EndpointClassIsProxied() {
public void should_Never_UseSpringObjectMapper() {
ApplicationContext contextMock = mock(ApplicationContext.class);
ObjectMapper mockSpringObjectMapper = mock(ObjectMapper.class);
ObjectMapper mockOwnObjectMapper = mock(ObjectMapper.class);
Jackson2ObjectMapperBuilder mockObjectMapperBuilder = mock(Jackson2ObjectMapperBuilder.class);
JacksonProperties mockJacksonProperties = mock(JacksonProperties.class);
when(contextMock.getBean(ObjectMapper.class))
.thenReturn(mockSpringObjectMapper);
when(contextMock.getBean(JacksonProperties.class))
.thenReturn(mockJacksonProperties);
when(contextMock.getBean(Jackson2ObjectMapperBuilder.class))
.thenReturn(mockObjectMapperBuilder);
when(mockObjectMapperBuilder.createXmlMapper(false))
.thenReturn(mockObjectMapperBuilder);
when(mockObjectMapperBuilder.build())
.thenReturn(mockOwnObjectMapper);
when(mockJacksonProperties.getVisibility())
.thenReturn(Collections.emptyMap());
new VaadinConnectController(null,
Expand All @@ -804,9 +811,45 @@ public void should_Never_UseSpringObjectMapper() {
mock(ExplicitNullableTypeChecker.class), contextMock);

verify(contextMock, never()).getBean(ObjectMapper.class);
verify(mockSpringObjectMapper, never()).setVisibility(
verify(contextMock, times(1)).getBean(Jackson2ObjectMapperBuilder.class);
verify(contextMock, times(1)).getBean(JacksonProperties.class);
verify(mockOwnObjectMapper, times(1)).setVisibility(
PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
}

@Test
public void should_NotOverrideVisibility_When_JacksonPropertiesProvideVisibility() {
ApplicationContext contextMock = mock(ApplicationContext.class);
ObjectMapper mockDefaultObjectMapper = mock(ObjectMapper.class);
ObjectMapper mockOwnObjectMapper = mock(ObjectMapper.class);
Jackson2ObjectMapperBuilder mockObjectMapperBuilder = mock(Jackson2ObjectMapperBuilder.class);
JacksonProperties mockJacksonProperties = mock(JacksonProperties.class);
when(contextMock.getBean(ObjectMapper.class))
.thenReturn(mockDefaultObjectMapper);
when(contextMock.getBean(JacksonProperties.class))
.thenReturn(mockJacksonProperties);
when(contextMock.getBean(Jackson2ObjectMapperBuilder.class))
.thenReturn(mockObjectMapperBuilder);
when(mockObjectMapperBuilder.createXmlMapper(false))
.thenReturn(mockObjectMapperBuilder);
when(mockObjectMapperBuilder.build())
.thenReturn(mockOwnObjectMapper);
when(mockJacksonProperties.getVisibility())
.thenReturn(Collections.singletonMap(PropertyAccessor.ALL,
JsonAutoDetect.Visibility.PUBLIC_ONLY));
new VaadinConnectController(null,
mock(VaadinConnectAccessChecker.class),
mock(EndpointNameChecker.class),
mock(ExplicitNullableTypeChecker.class),
contextMock);

verify(contextMock, never()).getBean(ObjectMapper.class);
verify(contextMock, times(1)).getBean(Jackson2ObjectMapperBuilder.class);
verify(mockDefaultObjectMapper, never()).setVisibility(
PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
verify(mockOwnObjectMapper, never()).setVisibility(
PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
verify(contextMock, never()).getBean(JacksonProperties.class);
verify(contextMock, times(1)).getBean(JacksonProperties.class);
}

@Test
Expand Down
@@ -0,0 +1,40 @@
/*
* Copyright 2000-2020 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package com.vaadin.flow.server.connect.rest;

import com.fasterxml.jackson.annotation.JsonProperty;

public class BeanWithJacksonAnnotation {
@JsonProperty("bookId")
private String id;
private String name;

@JsonProperty("name")
public void setFirstName(String name) {
this.name = name;
}

@JsonProperty("name")
public String getFirstName() {
return name;
}

@JsonProperty
public int getRating() {
return 2;
}
}
@@ -0,0 +1,40 @@
/*
* Copyright 2000-2020 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package com.vaadin.flow.server.connect.rest;

public class BeanWithPrivateFields {
@SuppressWarnings("unused")
private String codeNumber = "007";
private String name = "Bond";
private String firstName = "James";

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

protected String getFirstName() {
return firstName;
}

protected void setFirstName(String firstName) {
this.firstName = firstName;
}
}

0 comments on commit 30a303e

Please sign in to comment.