|
|
|
@ -0,0 +1,168 @@ |
|
|
|
package com.inspect.ivs.service; |
|
|
|
|
|
|
|
import com.inspect.base.core.utils.StringUtils; |
|
|
|
import com.inspect.ivs.constant.IvsConst; |
|
|
|
import com.inspect.ivs.util.UriUtils; |
|
|
|
import com.inspect.ivs.view.IvsPlatformSnapshotView; |
|
|
|
import com.inspect.ivs.view.IvsSnapshotView; |
|
|
|
import com.inspect.ivs.vo.IvsChanSnapVo; |
|
|
|
import com.inspect.ivs.vo.IvsDevChanSnapVo; |
|
|
|
import org.apache.http.HttpResponse; |
|
|
|
import org.apache.http.client.methods.HttpGet; |
|
|
|
import org.apache.http.impl.client.CloseableHttpClient; |
|
|
|
import org.apache.http.impl.client.HttpClients; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
import org.springframework.core.io.InputStreamResource; |
|
|
|
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.retry.support.RetrySynchronizationManager; |
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
|
|
|
|
import javax.annotation.Resource; |
|
|
|
import javax.imageio.ImageIO; |
|
|
|
import java.awt.*; |
|
|
|
import java.awt.image.BufferedImage; |
|
|
|
import java.io.ByteArrayInputStream; |
|
|
|
import java.io.ByteArrayOutputStream; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.util.UUID; |
|
|
|
|
|
|
|
@Component |
|
|
|
public class IvsResourceRetryableDelegate { |
|
|
|
private static final Logger log = LoggerFactory.getLogger(IvsResourceRetryableDelegate.class); |
|
|
|
|
|
|
|
private static final int RETRYABLE_MAX = 10; |
|
|
|
|
|
|
|
@Resource |
|
|
|
private IvsCommonService ivsCommonService; |
|
|
|
|
|
|
|
@Retryable( |
|
|
|
value = IOException.class, |
|
|
|
maxAttempts = RETRYABLE_MAX, |
|
|
|
backoff = @Backoff(delay = 2000)) // 每次重试间隔 2 秒 |
|
|
|
public IvsSnapshotView getSnapshotRetryable(IvsDevChanSnapVo ivsDevChanSnapVo) throws IOException { |
|
|
|
int retryCount = RetrySynchronizationManager.getContext() != null |
|
|
|
? RetrySynchronizationManager.getContext().getRetryCount() + 1 |
|
|
|
: 1; |
|
|
|
log.info("URI_PLATFORM_SNAPSHOT retryCount: {}, UUID: {}", retryCount, ivsDevChanSnapVo.getUUID()); |
|
|
|
IvsSnapshotView ivsSnapshotView; |
|
|
|
try { |
|
|
|
ivsSnapshotView = ivsCommonService.get(getLabel(), UriUtils.parse(IvsConst.URI_PLATFORM_SNAPSHOT, ivsDevChanSnapVo), IvsSnapshotView.class); |
|
|
|
log.info("URI_PLATFORM_SNAPSHOT SUCCESS retryCount: {}, UUID: {}", retryCount, ivsDevChanSnapVo.getUUID()); |
|
|
|
} catch (Exception e) { |
|
|
|
log.info("URI_PLATFORM_SNAPSHOT FAIL retryCount: {}, UUID: {}", retryCount, ivsDevChanSnapVo.getUUID()); |
|
|
|
throw new IOException("URI_PLATFORM_SNAPSHOT FAIL UUID: " + ivsDevChanSnapVo.getUUID()); |
|
|
|
} |
|
|
|
|
|
|
|
return ivsSnapshotView; |
|
|
|
} |
|
|
|
|
|
|
|
@SuppressWarnings("unused") |
|
|
|
@Recover |
|
|
|
public IvsSnapshotView recover(IOException e, IvsDevChanSnapVo ivsDevChanSnapVo) { |
|
|
|
log.info("URI_PLATFORM_SNAPSHOT RECOVER UUID: {}, MSG: {}", ivsDevChanSnapVo.getUUID(), e.getMessage()); |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
@Retryable( |
|
|
|
value = IOException.class, |
|
|
|
maxAttempts = RETRYABLE_MAX, |
|
|
|
backoff = @Backoff(delay = 2000)) // 每次重试间隔 2 秒 |
|
|
|
public IvsPlatformSnapshotView getSnapshotListRetryable(final IvsChanSnapVo ivsChanSnapVo) throws IOException { |
|
|
|
int retryCount = RetrySynchronizationManager.getContext() != null |
|
|
|
? RetrySynchronizationManager.getContext().getRetryCount() + 1 |
|
|
|
: 1; |
|
|
|
log.info("URI_SNAPSHOT_LIST retryCount: {}, UUID: {}", retryCount, ivsChanSnapVo.getUUID()); |
|
|
|
IvsPlatformSnapshotView snapShotView; |
|
|
|
try { |
|
|
|
snapShotView = ivsCommonService.postJson(getLabel(), ivsChanSnapVo, IvsConst.URI_SNAPSHOT_LIST, IvsPlatformSnapshotView.class); |
|
|
|
log.info("URI_SNAPSHOT_LIST SUCCESS retryCount: {}, UUID: {}", retryCount, ivsChanSnapVo.getUUID()); |
|
|
|
} catch (Exception e) { |
|
|
|
log.info("URI_SNAPSHOT_LIST FAIL retryCount: {}, UUID: {}", retryCount, ivsChanSnapVo.getUUID()); |
|
|
|
throw new IOException("URI_SNAPSHOT_LIST FAIL UUID: " + ivsChanSnapVo.getUUID()); |
|
|
|
} |
|
|
|
|
|
|
|
return snapShotView; |
|
|
|
} |
|
|
|
|
|
|
|
@SuppressWarnings("unused") |
|
|
|
@Recover |
|
|
|
public IvsPlatformSnapshotView recover(IOException e, IvsChanSnapVo ivsChanSnapVo) { |
|
|
|
log.info("URI_SNAPSHOT_LIST RECOVER UUID: {}, MSG: {}", ivsChanSnapVo.getUUID(), e.getMessage()); |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
@Retryable( |
|
|
|
value = IOException.class, |
|
|
|
maxAttempts = RETRYABLE_MAX, |
|
|
|
backoff = @Backoff(delay = 2000)) // 每次重试间隔 2 秒 |
|
|
|
public ResponseEntity<InputStreamResource> downloadPictureRetryable(String uuid, String pictureUrl) throws IOException { |
|
|
|
int retryCount = RetrySynchronizationManager.getContext() != null |
|
|
|
? RetrySynchronizationManager.getContext().getRetryCount() + 1 |
|
|
|
: 1; |
|
|
|
|
|
|
|
log.info("DOWNLOAD_PICTURE retryCount: {}, pictureUrl: {}, UUID: {}", retryCount, pictureUrl, uuid); |
|
|
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) { |
|
|
|
HttpResponse httpResponse = httpClient.execute(new HttpGet(pictureUrl)); |
|
|
|
InputStream content = httpResponse.getEntity().getContent(); |
|
|
|
byte[] bytes = readStream(content); |
|
|
|
log.info("DOWNLOAD_PICTURE retryCount: {}, SIZE: {}, UUID: {}", retryCount, bytes.length, uuid); |
|
|
|
if (bytes.length > 0) { |
|
|
|
InputStream inputStream = new ByteArrayInputStream(bytes); |
|
|
|
return ResponseEntity.ok().body(new InputStreamResource(inputStream)); |
|
|
|
} else { |
|
|
|
throw new IOException("DOWNLOAD_PICTURE PIC NULL: " + pictureUrl + ", UUID: " + uuid); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@SuppressWarnings("unused") |
|
|
|
@Recover |
|
|
|
public ResponseEntity<InputStreamResource> recover(IOException e, String uuid, String pictureUrl) { |
|
|
|
log.info("DOWNLOAD_PICTURE RECOVER {}, UUID: {}, MSG: {}", pictureUrl, uuid, e.getMessage()); |
|
|
|
return ResponseEntity.ok().body(new InputStreamResource(generateErrorImage())); |
|
|
|
} |
|
|
|
|
|
|
|
public static byte[] readStream(InputStream inputStream) throws IOException { |
|
|
|
try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()) { |
|
|
|
byte[] buffer = new byte[4096]; // 4KB 缓冲区 |
|
|
|
int len; |
|
|
|
while ((len = inputStream.read(buffer)) != -1) { |
|
|
|
outStream.write(buffer, 0, len); |
|
|
|
} |
|
|
|
return outStream.toByteArray(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public InputStream generateErrorImage() { |
|
|
|
int width = 400, height = 200; |
|
|
|
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); |
|
|
|
Graphics2D g = bufferedImage.createGraphics(); |
|
|
|
|
|
|
|
// 背景 |
|
|
|
g.setColor(Color.WHITE); |
|
|
|
g.fillRect(0, 0, width, height); |
|
|
|
|
|
|
|
// 字体 |
|
|
|
g.setColor(Color.RED); |
|
|
|
g.setFont(new Font("Arial", Font.BOLD, 20)); |
|
|
|
g.drawString("Get Picture Fail", 120, 100); |
|
|
|
g.dispose(); |
|
|
|
|
|
|
|
try { |
|
|
|
ByteArrayOutputStream os = new ByteArrayOutputStream(); |
|
|
|
ImageIO.write(bufferedImage, "png", os); |
|
|
|
return new ByteArrayInputStream(os.toByteArray()); |
|
|
|
} catch (IOException e) { |
|
|
|
throw new RuntimeException("生成错误图片失败", e); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public String getLabel() { |
|
|
|
return UUID.randomUUID().toString().trim().replaceAll(StringUtils.DASH, StringUtils.EMPTY); |
|
|
|
} |
|
|
|
} |