Skip to content

Commit

Permalink
Add fallback behavior for Posts service timeout problems
Browse files Browse the repository at this point in the history
  • Loading branch information
cdavisafc committed Feb 18, 2019
1 parent 47f3fbb commit 29a250d
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 78 deletions.

This file was deleted.

4 changes: 2 additions & 2 deletions cloudnative-requestresilience/buildAndPushDockerImages.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
docker build --build-arg \
jar_file=cloudnative-connectionposts/target/cloudnative-connectionposts-0.0.1-SNAPSHOT.jar \
-t cdavisafc/cloudnative-requestresilience-connectionposts:0.0.2 .
-t cdavisafc/cloudnative-requestresilience-connectionposts:0.0.3 .
# only connections posts has changed for this step
#
docker push cdavisafc/cloudnative-requestresilience-connectionposts:0.0.2
docker push cdavisafc/cloudnative-requestresilience-connectionposts:0.0.3
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.retry.annotation.EnableRetry;


Expand All @@ -21,6 +22,7 @@
@SpringBootApplication
@ComponentScan(basePackages = { "com.corneliadavis.cloudnative.*" })
@EntityScan("com.corneliadavis.cloudnative.*")
@EnableRedisRepositories("com.corneliadavis.cloudnative.*")
public class CloudnativeApplication {

@Value("${redis.hostname}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ public String getName() {
@Value("${connectionpostscontroller.readTimeout}")
private int readTimeout;

private StringRedisTemplate template;
private StringRedisTemplate stringRedisTemplate;

private boolean isHealthy = true;

@Autowired
public ConnectionsPostsController(StringRedisTemplate template) {
this.template = template;
this.stringRedisTemplate = template;
}

@Autowired
Expand All @@ -117,7 +117,7 @@ public Iterable<PostSummary> getByUsername(@CookieValue(value = "userToken", req
logger.info(utils.ipTag() + "connectionsPosts access attempt without auth token");
response.setStatus(401);
} else {
ValueOperations<String, String> ops = this.template.opsForValue();
ValueOperations<String, String> ops = this.stringRedisTemplate.opsForValue();
String username = ops.get(token);
if (username == null) {
logger.info(utils.ipTag() + "connectionsPosts access attempt with invalid token");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.corneliadavis.cloudnative.connectionsposts;

import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;

import java.io.Serializable;

@RedisHash("PostSummaries")
public class PostResults implements Serializable {
@Id
private String ids;
private String summariesJson;

public PostResults (String ids, String summariesJson) {

this.ids = ids;
this.summariesJson = summariesJson;
}

public String getSummariesJson() {
return summariesJson;
}

public String getIds() {
return ids;
}


}

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public PostSummary(String usersname, String title, Date date) {
this.title = title;
}

public PostSummary() {}

public Date getDate() {
return date;
}
Expand All @@ -29,4 +31,15 @@ public String getTitle() {
return title;
}

public void setDate(Date date) {
this.date = date;
}

public void setUsersname(String usersname) {
this.usersname = usersname;
}

public void setTitle(String title) {
this.title = title;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.corneliadavis.cloudnative.connectionsposts;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface PostsResultsRepository extends CrudRepository<PostResults, String> {
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
package com.corneliadavis.cloudnative.connectionsposts;

import com.corneliadavis.cloudnative.Utils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;

@Service
public class PostsServiceClient {

private PostsResultsRepository postResultsRepository;

private static final Logger logger = LoggerFactory.getLogger(ConnectionsPostsController.class);

@Value("${connectionpostscontroller.postsUrl}")
Expand All @@ -27,7 +33,12 @@ public class PostsServiceClient {
@Autowired
Utils utils;

@Retryable( value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 1000))
@Autowired
public PostsServiceClient(PostsResultsRepository postResultsRepository) {
this.postResultsRepository = postResultsRepository;
}

@Retryable( value = ResourceAccessException.class, maxAttempts = 3, backoff = @Backoff(delay = 500))
public ArrayList<PostSummary> getPosts(String ids, RestTemplate restTemplate) throws Exception {

ArrayList<PostSummary> postSummaries = new ArrayList<PostSummary>();
Expand All @@ -43,11 +54,32 @@ public ArrayList<PostSummary> getPosts(String ids, RestTemplate restTemplate) th
ConnectionsPostsController.PostResult[] posts = respPosts.getBody();
for (int i = 0; i < posts.length; i++)
postSummaries.add(new PostSummary(getUsersname(posts[i].getUserId(), restTemplate), posts[i].getTitle(), posts[i].getDate()));
ObjectMapper objectMapper = new ObjectMapper();
String postSummariesJson = objectMapper.writeValueAsString(postSummaries);
PostResults postResults = new PostResults(ids, postSummariesJson);
postResultsRepository.save(postResults);
return postSummaries;
}

}

@Recover
public ArrayList<PostSummary> returnCached(ResourceAccessException e, String ids, RestTemplate restTemplate) throws Exception {
logger.info("Failed to connect to or obtain results from Posts service - returning cached results");

PostResults postResults = postResultsRepository.findById(ids).get();
ObjectMapper objectMapper = new ObjectMapper();
ArrayList<PostSummary> postSummaries;
try {
postSummaries = objectMapper.readValue(postResults.getSummariesJson(), new TypeReference<ArrayList<PostSummary>>() {});
} catch (Exception ec) {
logger.info("Exception on deserialization " + ec.getClass() + " message = " + ec.getMessage());
return null;
}
return postSummaries;

}

private String getUsersname(Long id, RestTemplate restTemplate) {
String secretQueryParam = "?secret=" + utils.getConnectionsSecret();
ResponseEntity<ConnectionsPostsController.UserResult> resp = restTemplate.getForEntity(usersUrl + id + secretQueryParam, ConnectionsPostsController.UserResult.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ spec:
spec:
containers:
- name: connectionsposts
image: cdavisafc/cloudnative-requestresilience-connectionposts:0.0.2
image: cdavisafc/cloudnative-requestresilience-connectionposts:0.0.3
# resources:
# limits:
# memory: "2048Mi"
Expand Down

0 comments on commit 29a250d

Please sign in to comment.