@@ -95,9 +95,7 @@ String body() {
9595 private enum Error {
9696 ALREADY_EXISTS(409, "global", "alreadyExists", "ALREADY_EXISTS"),
9797 PERMISSION_DENIED(403, "global", "forbidden", "PERMISSION_DENIED"),
98- // change failed precondition error code to 412 when #440 is fixed
9998 FAILED_PRECONDITION(400, "global", "failedPrecondition", "FAILED_PRECONDITION"),
100- // change invalid argument error code to 412 when #440 is fixed
10199 INVALID_ARGUMENT(400, "global", "badRequest", "INVALID_ARGUMENT"),
102100 BAD_REQUEST(400, "global", "badRequest", "BAD_REQUEST"),
103101 INTERNAL_ERROR(500, "global", "internalError", "INTERNAL_ERROR");
@@ -324,12 +322,9 @@ Response create(Project project) {
324322 }
325323 }
326324
327- Response delete(String projectId) {
325+ synchronized Response delete(String projectId) {
328326 Project project = projects.get(projectId);
329327 if (project == null) {
330- // Currently the service returns 403 Permission Denied when trying to delete a project that
331- // doesn't exist. Here we mimic this behavior, but this line should be changed to throw a
332- // 404 Not Found error when the service fixes this (#440).
333328 return Error.PERMISSION_DENIED.response(
334329 "Error when deleting " + projectId + " because the project was not found.");
335330 }
@@ -343,18 +338,16 @@ Response delete(String projectId) {
343338 }
344339
345340 Response get(String projectId, String[] fields) {
346- if (!projects.containsKey(projectId)) {
347- // Currently the service returns 403 Permission Denied when trying to get a project that
348- // doesn't exist. Here we mimic this behavior, but this line should be changed to throw a
349- // 404 Not Found error when the service fixes this (#440).
350- return Error.PERMISSION_DENIED.response("Project " + projectId + " not found.");
351- }
352341 Project project = projects.get(projectId);
353- try {
354- return new Response(HTTP_OK, jsonFactory.toString(extractFields(project, fields)));
355- } catch (IOException e) {
356- return Error.INTERNAL_ERROR.response(
357- "Error when serializing project " + project.getProjectId());
342+ if (project != null) {
343+ try {
344+ return new Response(HTTP_OK, jsonFactory.toString(extractFields(project, fields)));
345+ } catch (IOException e) {
346+ return Error.INTERNAL_ERROR.response(
347+ "Error when serializing project " + project.getProjectId());
348+ }
349+ } else {
350+ return Error.PERMISSION_DENIED.response("Project " + projectId + " not found.");
358351 }
359352 }
360353
@@ -462,12 +455,9 @@ private static Project extractFields(Project fullProject, String[] fields) {
462455 return project;
463456 }
464457
465- Response replace(String projectId, Project project) {
458+ synchronized Response replace(String projectId, Project project) {
466459 Project originalProject = projects.get(projectId);
467460 if (originalProject == null) {
468- // Currently the service returns 403 Permission Denied when trying to replace a project that
469- // doesn't exist. Here we mimic this behavior, but this line should be changed to throw a
470- // 404 Not Found error when the service fixes this (#440).
471461 return Error.PERMISSION_DENIED.response(
472462 "Error when replacing " + projectId + " because the project was not found.");
473463 } else if (!originalProject.getLifecycleState().equals("ACTIVE")) {
@@ -478,23 +468,23 @@ Response replace(String projectId, Project project) {
478468 "The server currently only supports setting the parent once "
479469 + "and does not allow unsetting it.");
480470 }
481- originalProject.setName(project.getName());
482- originalProject.setLabels(project.getLabels());
483- originalProject.setParent(project.getParent());
471+ project.setProjectId(projectId);
472+ project.setLifecycleState(originalProject.getLifecycleState());
473+ project.setCreateTime(originalProject.getCreateTime());
474+ project.setProjectNumber(originalProject.getProjectNumber());
475+ // replace cannot fail because both this method and removeProject are synchronized
476+ projects.replace(projectId, project);
484477 try {
485- return new Response(HTTP_OK, jsonFactory.toString(originalProject ));
478+ return new Response(HTTP_OK, jsonFactory.toString(project ));
486479 } catch (IOException e) {
487480 return Error.INTERNAL_ERROR.response("Error when serializing project " + projectId);
488481 }
489482 }
490483
491- Response undelete(String projectId) {
484+ synchronized Response undelete(String projectId) {
492485 Project project = projects.get(projectId);
493486 Response response;
494487 if (project == null) {
495- // Currently the service returns 403 Permission Denied when trying to undelete a project that
496- // doesn't exist. Here we mimic this behavior, but this line should be changed to throw a
497- // 404 Not Found error when the service fixes this (#440).
498488 response = Error.PERMISSION_DENIED.response(
499489 "Error when undeleting " + projectId + " because the project was not found.");
500490 } else if (!project.getLifecycleState().equals("DELETE_REQUESTED")) {
@@ -550,7 +540,7 @@ public void stop() {
550540 *
551541 * @return true if the lifecycle state was successfully updated, false otherwise.
552542 */
553- public boolean changeLifecycleState(String projectId, String lifecycleState) {
543+ public synchronized boolean changeLifecycleState(String projectId, String lifecycleState) {
554544 checkArgument(
555545 "ACTIVE".equals(lifecycleState) || "DELETE_REQUESTED".equals(lifecycleState)
556546 || "DELETE_IN_PROGRESS".equals(lifecycleState),
@@ -571,7 +561,9 @@ public boolean changeLifecycleState(String projectId, String lifecycleState) {
571561 *
572562 * @return true if the project was successfully deleted, false if the project didn't exist.
573563 */
574- public boolean removeProject(String projectId) {
564+ public synchronized boolean removeProject(String projectId) {
565+ // Because this method is synchronized, any code that relies on non-atomic read/write operations
566+ // should not fail if that code is also synchronized.
575567 return projects.remove(checkNotNull(projectId)) != null;
576568 }
577569}
0 commit comments