From 913585a8f7171849bc803e9d7bb1ba6f0ff05d84 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Wed, 29 Nov 2017 22:22:23 +0300 Subject: www: purge avatar cache from Cloudflare --- .../juick/server/component/UserUpdatedEvent.java | 23 +++++++++ .../java/com/juick/service/CloudflareCache.java | 56 ++++++++++++++++++++++ .../com/juick/service/cloudflare/FilesPayload.java | 20 ++++++++ .../www/configuration/WwwAppConfiguration.java | 5 ++ .../java/com/juick/www/controllers/Settings.java | 12 ++--- 5 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 juick-server-web/src/main/java/com/juick/server/component/UserUpdatedEvent.java create mode 100644 juick-www/src/main/java/com/juick/service/CloudflareCache.java create mode 100644 juick-www/src/main/java/com/juick/service/cloudflare/FilesPayload.java diff --git a/juick-server-web/src/main/java/com/juick/server/component/UserUpdatedEvent.java b/juick-server-web/src/main/java/com/juick/server/component/UserUpdatedEvent.java new file mode 100644 index 00000000..059aeefd --- /dev/null +++ b/juick-server-web/src/main/java/com/juick/server/component/UserUpdatedEvent.java @@ -0,0 +1,23 @@ +package com.juick.server.component; + +import com.juick.User; +import org.springframework.context.ApplicationEvent; +import org.springframework.lang.NonNull; + +public class UserUpdatedEvent extends ApplicationEvent { + private User user; + /** + * Generated when user is updated (avatar changed, etc). + * + * @param source the object on which the event initially occurred (never {@code null}) + * @param user updated user + */ + public UserUpdatedEvent(@NonNull Object source, User user) { + super(source); + this.user = user; + } + + public User getUser() { + return user; + } +} diff --git a/juick-www/src/main/java/com/juick/service/CloudflareCache.java b/juick-www/src/main/java/com/juick/service/CloudflareCache.java new file mode 100644 index 00000000..00e1f684 --- /dev/null +++ b/juick-www/src/main/java/com/juick/service/CloudflareCache.java @@ -0,0 +1,56 @@ +package com.juick.service; + +import com.juick.service.cloudflare.FilesPayload; +import com.juick.User; +import com.juick.server.component.UserUpdatedEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationListener; +import org.springframework.http.*; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +import java.util.Arrays; +import java.util.Collections; + +public class CloudflareCache implements ApplicationListener { + private static final Logger logger = LoggerFactory.getLogger(CloudflareCache.class); + @Value("${cloudflare_auth_email}") + private String authEmail; + @Value("${cloudflare_api_key}") + private String apiKey; + @Value("${cloudflare_zone_id}") + private String zoneId; + private final static String baseUri = "https://api.cloudflare.com/client/v4"; + @Override + public void onApplicationEvent(UserUpdatedEvent event) { + User user = event.getUser(); + logger.debug("Purging Cloudflare cache for {} avatar", user.getName()); + UriComponents uriComponents = UriComponentsBuilder.fromUriString("{baseUri}/zones/{zoneId}/purge_cache") + .buildAndExpand(baseUri, zoneId); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add("X-Auth-Email", authEmail); + httpHeaders.add("X-Auth-Key", apiKey); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + FilesPayload payload = new FilesPayload(); + payload.setFiles(Arrays.asList( + String.format("http://i.juick.com/a/%d.png", user.getUid()), + String.format("http://i.juick.com/as/%d.png", user.getUid()), + String.format("http://i.juick.com/a/%d.jpg", user.getUid()), + String.format("http://i.juick.com/as/%d.jpg", user.getUid()), + String.format("https://i.juick.com/a/%d.png", user.getUid()), + String.format("https://i.juick.com/as/%d.png", user.getUid()), + String.format("https://i.juick.com/a/%d.jpg", user.getUid()), + String.format("https://i.juick.com/as/%d.jpg", user.getUid()) + )); + RestTemplate api = new RestTemplate(); + api.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); + ResponseEntity response = api.exchange(uriComponents.toUri(), + HttpMethod.DELETE, + new HttpEntity<>(payload, httpHeaders), String.class); + logger.info("Cloudflare response: {}", response.getBody()); + } +} diff --git a/juick-www/src/main/java/com/juick/service/cloudflare/FilesPayload.java b/juick-www/src/main/java/com/juick/service/cloudflare/FilesPayload.java new file mode 100644 index 00000000..35d9e72f --- /dev/null +++ b/juick-www/src/main/java/com/juick/service/cloudflare/FilesPayload.java @@ -0,0 +1,20 @@ +package com.juick.service.cloudflare; + +import java.util.ArrayList; +import java.util.List; + +public class FilesPayload { + private List files; + + public FilesPayload() { + files = new ArrayList<>(); + } + + public List getFiles() { + return files; + } + + public void setFiles(List files) { + this.files = files; + } +} diff --git a/juick-www/src/main/java/com/juick/www/configuration/WwwAppConfiguration.java b/juick-www/src/main/java/com/juick/www/configuration/WwwAppConfiguration.java index d79ae636..205c0627 100644 --- a/juick-www/src/main/java/com/juick/www/configuration/WwwAppConfiguration.java +++ b/juick-www/src/main/java/com/juick/www/configuration/WwwAppConfiguration.java @@ -19,6 +19,7 @@ package com.juick.www.configuration; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import com.juick.service.CloudflareCache; import com.juick.service.TagService; import com.juick.service.UserService; import com.juick.www.HelpService; @@ -93,5 +94,9 @@ public class WwwAppConfiguration { }) .build(); } + @Bean + public CloudflareCache cloudflareCache() { + return new CloudflareCache(); + } } diff --git a/juick-www/src/main/java/com/juick/www/controllers/Settings.java b/juick-www/src/main/java/com/juick/www/controllers/Settings.java index db60acba..64775aec 100644 --- a/juick-www/src/main/java/com/juick/www/controllers/Settings.java +++ b/juick-www/src/main/java/com/juick/www/controllers/Settings.java @@ -16,19 +16,16 @@ */ package com.juick.www.controllers; +import com.juick.server.component.UserUpdatedEvent; import com.juick.server.helpers.NotifyOpts; import com.juick.server.helpers.UserInfo; -import com.juick.server.util.HashUtils; +import com.juick.server.util.*; import com.juick.service.*; -import com.juick.server.util.HttpBadRequestException; -import com.juick.server.util.HttpUtils; -import com.juick.server.util.ImageUtils; -import com.juick.server.util.UserUtils; -import com.juick.www.WebApp; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; @@ -77,6 +74,8 @@ public class Settings { private EmailService emailService; @Inject private TelegramService telegramService; + @Inject + private ApplicationEventPublisher applicationEventPublisher; @GetMapping("/settings") protected String doGet(HttpServletRequest request, HttpServletResponse response, ModelMap model) throws IOException { @@ -164,6 +163,7 @@ public class Settings { ImageUtils.saveAvatar(avatarTmpPath, visitor.getUid(), tmpDir, imgDir); } if (userService.updateUserInfo(visitor, info)) { + applicationEventPublisher.publishEvent(new UserUpdatedEvent(this, visitor)); result = String.format("

Your info is updated.

Back to blog.

", visitor.getName()); } break; -- cgit v1.2.3