Skip to content

Commit

Permalink
Add ignoreUnknownProperties option (#136)
Browse files Browse the repository at this point in the history
* Add ignoreUnknownProperties option

When Mattermost Server api response changed, you can suppress JsonMappingException by ignoreUnknownProperties = true by using MattermostClientBuilder#ignoreUnknownProperties().

* Add default constructor that use in~ ClientBuilder#register(Class<?>)

* Add test cases

* Update usage
  • Loading branch information
maruTA-bis5 authored Jan 24, 2019
1 parent 494d711 commit 05a089c
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 6 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,16 @@ Mattermost API v4 client for Java.
## Usage
### Basic API Client
```java
MattermostClient client = new MattermostClient("YOUR-MATTERMOST-URL");
// Create client instance
MattermostClient client;
// case 1. use constructor - log disable and prohibit unknown properties
client = new MattermostClient("YOUR-MATTERMOST-URL");
// case 2. use builder
client = MattermostClient.builder()
.url("YOUR-MATTERMOST-URL")
.logLevel(Level.INFO)
.ignoreUnknownProperties()
.build();

// Login by id + password
client.login(loginId, password);
Expand All @@ -27,6 +36,7 @@ client.setAccessToken(token);

### Use Incoming Webhook
```
// You can also use builder for create client instance.
MattermostClient client = new MattermostClient("YOUR-MATTERMOST-URL")
IncomingWebhookRequest payload = new IncomingWebhookRequest();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,41 @@ public class MattermostClient
private String authToken;
private AuthType authType;
private final Level clientLogLevel;
private final boolean ignoreUnknownProperties;
private final Client httpClient;

public static MattermostClientBuilder builder() {
return new MattermostClientBuilder();
}

public static class MattermostClientBuilder {
private Level logLevel;
private String url;
private boolean ignoreUnknownProperties;

public MattermostClientBuilder logLevel(Level logLevel) {
this.logLevel = logLevel;
return this;
}

public MattermostClientBuilder url(String url) {
this.url = url;
return this;
}

public MattermostClientBuilder ignoreUnknownProperties() {
this.ignoreUnknownProperties = true;
return this;
}

public MattermostClient build() {
return new MattermostClient(url, logLevel, ignoreUnknownProperties);
}
}

protected Client buildClient() {
ClientBuilder builder = ClientBuilder.newBuilder().register(MattermostModelMapperProvider.class)
ClientBuilder builder = ClientBuilder.newBuilder()
.register(new MattermostModelMapperProvider(ignoreUnknownProperties))
.register(JacksonFeature.class).register(MultiPartFeature.class)
// needs for PUT request with null entity
// (/commands/{command_id}/regen_token)
Expand All @@ -195,12 +226,18 @@ public MattermostClient(String url) {
* Create new MattermosClient instance.
*/
public MattermostClient(String url, Level logLevel) {
this(url, logLevel, false);
}

MattermostClient(String url, Level logLevel, boolean ignoreUnknownProperties) {
this.url = url;
this.apiUrl = url + API_URL_SUFFIX;
this.clientLogLevel = logLevel;
this.ignoreUnknownProperties = ignoreUnknownProperties;
this.httpClient = buildClient();
}


public void setOAuthToken(String token) {
this.authToken = token;
this.authType = AuthType.TOKEN;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package net.bis5.mattermost.jersey.provider;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.ws.rs.ext.ContextResolver;
Expand All @@ -29,10 +30,22 @@
@Provider
public class MattermostModelMapperProvider implements ContextResolver<ObjectMapper> {

final ObjectMapper defaultObjectMapper = createDefaultObjectMapper();
final ObjectMapper defaultObjectMapper;
private final boolean ignoreUnknownProperties;

public MattermostModelMapperProvider() {
this(false);
}

public MattermostModelMapperProvider(boolean ignoreUnknownProperties) {
this.ignoreUnknownProperties = ignoreUnknownProperties;
defaultObjectMapper = createDefaultObjectMapper();
}


protected ObjectMapper createDefaultObjectMapper() {
return new ObjectMapper().configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, !ignoreUnknownProperties)
.setSerializationInclusion(Include.NON_EMPTY)
.setPropertyNamingStrategy(new MattermostPropertyNamingStrategy());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,19 @@ private static String getInbucketPort() {

@BeforeAll
public static void initHelper() {
th = new TestHelper(new MattermostClient(APPLICATION)).setup();
th = new TestHelper(createNewClient()).setup();
}

private static MattermostClient createNewClient() {
return MattermostClient.builder() //
.url(APPLICATION) //
.logLevel(Level.WARNING) //
.build();
}

@BeforeEach
public void setup() {
client = new MattermostClient(APPLICATION, Level.WARNING);
client = createNewClient();
th.changeClient(client).initBasic();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.Arrays;
import java.util.stream.Collectors;
import javax.ws.rs.ProcessingException;
import javax.ws.rs.core.Response.Status;
import lombok.Getter;
import lombok.experimental.Accessors;
import net.bis5.mattermost.client4.model.ApiError;
Expand Down Expand Up @@ -294,8 +295,14 @@ public TestHelper updateUserToNonTeamAdmin(User user, Team team) {
public <T> ApiResponse<T> checkNoError(ApiResponse<T> response) {
response.getRawResponse().bufferEntity();
try {
// if ignoreUnknownProperty is true, no exception will be thrown
ApiError error = response.readError();
throw new AssertionError("Expected no error, got " + error);
Status.Family responseStatus = Status.Family.familyOf(error.getStatusCode());
if (responseStatus == Status.Family.CLIENT_ERROR
|| responseStatus == Status.Family.SERVER_ERROR) {
throw new AssertionError("Expected no error, got " + error);
}
// no error
} catch (ProcessingException ex) {
// no error
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2019 Takayuki Maruyama
*
* 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 net.bis5.mattermost.jersey.provider;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import javax.ws.rs.ext.ContextResolver;
import net.bis5.mattermost.model.User;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

/**
* Test cases for {@link MattermostModelMapperProvider}.
*/
public class MattermostModelMapperProviderTest {

@Nested
static class IgnoreUnknownPropertiesTest {
private static final String JSON_INCLUDE_UNKNOWN_PROPERTY = //
"{\"UNKNOWN_PROPERTY\":\"value\",\"id\":\"qjwhr6gcq3d8d883cgsuk17h9a\"}";

@Test
public void ignoreUnknownPropertyCorrectly()
throws JsonParseException, JsonMappingException, IOException {
ContextResolver<ObjectMapper> provider = new MattermostModelMapperProvider(true);
ObjectMapper objectMapper = provider.getContext(ObjectMapper.class);

User user = objectMapper.readValue(JSON_INCLUDE_UNKNOWN_PROPERTY, User.class);
assertNotNull(user);
}

@Test
public void throwExceptionStrict() {
ContextResolver<ObjectMapper> provider = new MattermostModelMapperProvider(false);
ObjectMapper objectMapper = provider.getContext(ObjectMapper.class);

assertThrows(JsonMappingException.class,
() -> objectMapper.readValue(JSON_INCLUDE_UNKNOWN_PROPERTY, User.class));
}
}
}

0 comments on commit 05a089c

Please sign in to comment.