spring boot 服務間傳輸Docker映象,並載入映象
阿新 • • 發佈:2018-12-19
springboot服務間介面呼叫很簡單,但是關於呼叫介面上傳檔案經常走彎路,故此總結一下:
負責上傳檔案的服務A():
@RequestMapping(value="/loadToRepository", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public Object loadImageToRepository (@RequestPart(value = "file") MultipartFile file) { logger.info("DockerUtils loadImageToRepository2 begin"); try { logger.info("docker映象名稱" + file.getOriginalFilename()); //由於檔案可能過大,導致頁面響應超時,故此處採用執行緒方式上傳 Thread uploadThread = new UploadThread(dockerHost, dockerUserName, dockerPassword, file.getInputStream()); uploadThread.start(); } catch (IOException e) { return ResultUtil.error(400, "獲取檔案流失敗"); } return ResultUtil.success("上傳結束,正在同步至映象倉庫"); }
public class UploadThread extends Thread { private final static Logger logger = LoggerFactory.getLogger(UploadThread.class); private String dockerHost; private String dockerUserName; private String dockerPassword; private InputStream inputStream; public UploadThread(String dockerHost, String dockerUserName, String dockerPassword, InputStream inputStream) { super(); this.dockerHost = dockerHost; this.dockerUserName = dockerUserName; this.dockerPassword = dockerPassword; this.inputStream = inputStream; } @Override public void run() { long beginTime = System.currentTimeMillis(); if (StringUtils.isEmpty(dockerUserName)) { dockerUserName = null; } if (StringUtils.isEmpty(dockerPassword)) { dockerPassword = null; } logger.info("dockerHost = " + dockerHost); logger.info("dockerUserName = " + dockerUserName); logger.info("dockerPassword = " + dockerPassword); DockerClientConfig dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder() .withRegistryUsername(dockerUserName) .withRegistryPassword(dockerPassword) .withDockerConfig(null) .withDockerHost(dockerHost).build(); DockerCmdExecFactory dockerCmdExecFactory = new JerseyDockerCmdExecFactory() .withReadTimeout(60000) .withConnectTimeout(1000) .withMaxTotalConnections(100) .withMaxPerRouteConnections(10); DockerClient dockerClient = DockerClientBuilder.getInstance(dockerClientConfig).withDockerCmdExecFactory(dockerCmdExecFactory).build(); logger.info("docker versin is " + dockerClient.versionCmd().exec().getVersion().toString()); // final Iterator<String> iterator = request.getFileNames(); MultipartFile multipartFile = null; // while (iterator.hasNext()) { // multipartFile = request.getFile(iterator.next()); // LoadImageCmd loadImageCmd = dockerClient.loadImageCmd(new FileInputStream(new File("C://Users//Administrator//Desktop//docker-java-api//mysql.tar"))); try { LoadImageCmd loadImageCmd = dockerClient.loadImageCmd(inputStream); loadImageCmd.exec(); } catch (Exception e) { e.printStackTrace(); logger.error("上傳Docker映象失敗"); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); logger.error("檔案流關閉失敗"); } } } // } long endTime = System.currentTimeMillis(); logger.info("上傳Docker映象結束,用時:" + (endTime - beginTime) + "ms"); } }
消費服務A上傳檔案介面的服務B:
public Map<String, Object> uploadInstall(final HttpServletRequest httpServletRequest, final String code) { logger.info("準備上傳映象至映象倉庫, tempPath=" + tempPath); new HttpClientUtils().uploadFile(dockerURL, file, tempPath); return resultMap; } public boolean uploadFile (String url, MultipartFile file, String tempPath) { HttpHeaders headers = new HttpHeaders(); String tempFileName = UUID.randomUUID() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); logger.info("tempPath = " + tempPath); String tempFilePath = tempPath + tempFileName; File tempFile = new File(tempFilePath); try { file.transferTo(tempFile); FileSystemResource fileSystemResource = new FileSystemResource(tempFilePath); logger.info("臨時檔案路徑:" + fileSystemResource.getPath()); MediaType type = MediaType.parseMediaType("multipart/form-data; charset=UTF-8"); headers.setContentType(type); String cd = "filename=\"" + file.getOriginalFilename() + "\""; headers.add("Content-Disposition", cd); MultiValueMap<String, Object> form = new LinkedMultiValueMap<String, Object>(); form.add("file", fileSystemResource); final RestTemplate restTemplate = new RestTemplate(); Object recv = restTemplate.postForEntity(url, form, Object.class); try { logger.info("呼叫上傳映象包介面返回的資料:" + recv.toString()); tempFile.delete(); } catch (Exception e) { e.printStackTrace(); } } catch (IllegalStateException e) { logger.error("httpclient close failed", e); } catch (IOException e) { logger.error("httpclient close failed", e); } return true; }