@@ -0,0 +1,3264 @@
+package com.google.sps.tasks;%0A%0Aimport com.github.dockerjava.api.DockerClient;%0Aimport com.github.dockerjava.api.async.ResultCallback;%0Aimport com.github.dockerjava.api.exception.DockerException;%0Aimport com.github.dockerjava.core.DefaultDockerClientConfig;%0Aimport com.github.dockerjava.core.DockerClientConfig;%0Aimport com.github.dockerjava.core.DockerClientImpl;%0Aimport com.github.dockerjava.httpclient5.ApacheDockerHttpClient;%0Aimport com.github.dockerjava.transport.DockerHttpClient;%0Aimport com.google.appengine.api.datastore.DatastoreService;%0Aimport com.google.appengine.api.datastore.DatastoreServiceFactory;%0Aimport com.google.appengine.api.datastore.Entity;%0Aimport com.google.appengine.api.datastore.EntityNotFoundException;%0Aimport com.google.appengine.api.datastore.KeyFactory;%0Aimport java.io.IOException;%0Aimport java.util.concurrent.TimeUnit;%0Aimport javax.servlet.ServletException;%0Aimport javax.servlet.annotation.WebServlet;%0Aimport javax.servlet.http.HttpServlet;%0Aimport javax.servlet.http.HttpServletRequest;%0Aimport javax.servlet.http.HttpServletResponse;%0A%0A@WebServlet(%22/tasks/pullEnv%22)%0Apublic class PullNewEnvironment extends HttpServlet %7B%0A  DockerClient docker;%0A%0A  @Override%0A  public void init() throws ServletException %7B%0A    DockerClientConfig cfg = DefaultDockerClientConfig.createDefaultConfigBuilder().build();%0A    DockerHttpClient httpClient =%0A        new ApacheDockerHttpClient.Builder()%0A            .dockerHost(cfg.getDockerHost())%0A            .sslConfig(cfg.getSSLConfig())%0A            .build();%0A    docker = DockerClientImpl.getInstance(cfg, httpClient);%0A  %7D%0A%0A  @Override%0A  protected void doPost(HttpServletRequest req, HttpServletResponse resp)%0A      throws ServletException, IOException %7B%0A    String body = req.getReader().lines().reduce(%22%22, (accumulator, actual) -%3E accumulator + actual);%0A%0A    String args%5B%5D = body.split(%22,%22);%0A%0A    String entityID = args%5B0%5D;%0A    String classID = args%5B1%5D;%0A    String registry = args%5B2%5D;%0A    String image = args%5B3%5D;%0A    String tag = args%5B4%5D;%0A%0A    String dockerSafeClassID = classID.replace(%22-%22, %22%22).toLowerCase();%0A%0A    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();%0A%0A    try %7B%0A      try %7B%0A        if (docker%0A            .pullImageCmd(image)%0A            .withTag(tag)%0A            .withRegistry(registry)%0A            .exec(new ResultCallback.Adapter%3C%3E())%0A            .awaitCompletion(5, TimeUnit.MINUTES)) %7B%0A%0A          docker.tagImageCmd(image, dockerSafeClassID + '-' + image, tag).exec();%0A%0A          docker.removeImageCmd(image).exec();%0A%0A          Entity e = datastore.get(KeyFactory.stringToKey(entityID));%0A          e.setProperty(%22status%22, %22ready%22);%0A          e.setProperty(%22image%22, dockerSafeClassID + '-' + image);%0A          e.setProperty(%22tag%22, tag);%0A          datastore.put(e);%0A        %7D else %7B%0A          Entity e = datastore.get(KeyFactory.stringToKey(entityID));%0A          e.setProperty(%22status%22, %22timeout%22);%0A          datastore.put(e);%0A        %7D%0A      %7D catch (InterruptedException %7C DockerException e) %7B%0A        Entity entity = datastore.get(KeyFactory.stringToKey(entityID));%0A        entity.setProperty(%22status%22, %22failed%22);%0A        datastore.put(entity);%0A      %7D%0A    %7D catch (EntityNotFoundException e) %7B%0A      resp.sendError(HttpServletResponse.SC_NOT_FOUND);%0A    %7D%0A  %7D%0A%7D%0A

Add servlet to pull new image.