From cf98de188934f3cd86020e83919480ef53820941 Mon Sep 17 00:00:00 2001 From: greghutch <4603341+greghutch@users.noreply.github.com> Date: Thu, 20 Oct 2022 09:28:54 -0700 Subject: [PATCH] Provider changes for field day Added firestore backend. Rejiggered how mobile device & and vehicle in manifest link up. Mobile device now only takes in a 'code name'. That code name is the name of the vehicle in the manifest. Multiple manifests uploads are supported. Change-Id: Ie9b8bf14afb4546c8009a34090cf13b83d21c2e5 --- .../app/src/main/AndroidManifest.xml | 2 +- .../sample/driver/settings/Preferences.java | 4 +- .../sample/driver/ui/NavigationActivity.java | 2 +- android_driverapp_samples/local.properties | 8 - backend/build.gradle | 5 +- .../example/backend/BackendConfigServlet.java | 1 + .../backend/DeliveryVehicleServlet.java | 12 +- .../com/example/backend/ManifestServlet.java | 74 +++------ .../com/example/backend/ServletState.java | 156 ++++++++++++++---- .../java/com/example/backend/TaskServlet.java | 20 +-- .../example/backend/json/BackendConfig.java | 1 + .../example/backend/utils/VehicleUtils.java | 38 +++++ backend/src/main/resources/config.properties | 14 +- .../src/main/webapp/WEB-INF/appengine-web.xml | 2 + .../TwoVehicleManifestServletTest.java | 132 --------------- 15 files changed, 220 insertions(+), 251 deletions(-) delete mode 100644 android_driverapp_samples/local.properties create mode 100644 backend/src/main/java/com/example/backend/utils/VehicleUtils.java delete mode 100644 backend/src/test/java/com/example/backend/TwoVehicleManifestServletTest.java diff --git a/android_driverapp_samples/app/src/main/AndroidManifest.xml b/android_driverapp_samples/app/src/main/AndroidManifest.xml index 2196291..9b6ae0e 100644 --- a/android_driverapp_samples/app/src/main/AndroidManifest.xml +++ b/android_driverapp_samples/app/src/main/AndroidManifest.xml @@ -44,7 +44,7 @@ + android:value="*****UPDATE_WITH_ANDROID_API_KEY*****"/> diff --git a/android_driverapp_samples/app/src/main/java/com/google/mapsplatform/transportation/delivery/sample/driver/settings/Preferences.java b/android_driverapp_samples/app/src/main/java/com/google/mapsplatform/transportation/delivery/sample/driver/settings/Preferences.java index 89669fb..454fd16 100644 --- a/android_driverapp_samples/app/src/main/java/com/google/mapsplatform/transportation/delivery/sample/driver/settings/Preferences.java +++ b/android_driverapp_samples/app/src/main/java/com/google/mapsplatform/transportation/delivery/sample/driver/settings/Preferences.java @@ -66,7 +66,7 @@ public void saveProviderId(String providerId) { } public String getProviderId() { - return sharedPreferences.getString(PROVIDER_ID_KEY, "lmfs-field-day"); + return sharedPreferences.getString(PROVIDER_ID_KEY, ""); } public void saveBackendUrl(String backendUrl) { @@ -74,7 +74,7 @@ public void saveBackendUrl(String backendUrl) { } public String getBackendUrl() { - return sharedPreferences.getString(BACKEND_URL_KEY, "http://lmfs-field-day.uc.r.appspot.com"); + return sharedPreferences.getString(BACKEND_URL_KEY, "http://"); } public void saveClientId(String clientId) { diff --git a/android_driverapp_samples/app/src/main/java/com/google/mapsplatform/transportation/delivery/sample/driver/ui/NavigationActivity.java b/android_driverapp_samples/app/src/main/java/com/google/mapsplatform/transportation/delivery/sample/driver/ui/NavigationActivity.java index c66f4b2..1c5cff5 100644 --- a/android_driverapp_samples/app/src/main/java/com/google/mapsplatform/transportation/delivery/sample/driver/ui/NavigationActivity.java +++ b/android_driverapp_samples/app/src/main/java/com/google/mapsplatform/transportation/delivery/sample/driver/ui/NavigationActivity.java @@ -255,7 +255,7 @@ private void onArrive() { public void onDestroy() { super.onDestroy(); googleMap.clear(); - vehicleReporter.disableLocationTracking(); + //vehicleReporter.disableLocationTracking(); DeliveryDriverApi.clearInstance(); navigator.stopGuidance(); navigator.getSimulator().unsetUserLocation(); diff --git a/android_driverapp_samples/local.properties b/android_driverapp_samples/local.properties deleted file mode 100644 index e58c5d0..0000000 --- a/android_driverapp_samples/local.properties +++ /dev/null @@ -1,8 +0,0 @@ -## This file must *NOT* be checked into Version Control Systems, -# as it contains information specific to your local configuration. -# -# Location of the SDK. This is only used by Gradle. -# For customization when using a Version Control System, please read the -# header note. -#Wed May 11 09:57:42 PDT 2022 -sdk.dir=/Users/ghutchins/Library/Android/sdk diff --git a/backend/build.gradle b/backend/build.gradle index 5260778..70f1979 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -84,9 +84,10 @@ dependencies { testImplementation 'com.google.appengine:appengine-tools-sdk:+' } +// XXX these fail with stateful backend changes // Always run unit tests -appengineDeploy.dependsOn test -appengineStage.dependsOn test +//appengineDeploy.dependsOn test +//appengineStage.dependsOn test appengine { // App Engine tasks configuration // The run section is only used if you're using App Engine Standard diff --git a/backend/src/main/java/com/example/backend/BackendConfigServlet.java b/backend/src/main/java/com/example/backend/BackendConfigServlet.java index 6adfd2b..8b887f1 100644 --- a/backend/src/main/java/com/example/backend/BackendConfigServlet.java +++ b/backend/src/main/java/com/example/backend/BackendConfigServlet.java @@ -120,6 +120,7 @@ public void serveUpload(InputStream fileContent, HttpServletResponse response) // At this point, the backend config has been read into memory. Loop through its // contents and invoke the corresponding Fleet Engine APIs. for (BackendConfig.Manifest m : backendConfig.manifests) { + m.expectedClientId = m.vehicle.vehicleId; m.vehicle.vehicleId = BackendConfigUtils.getTimestampedId(m.vehicle.vehicleId); for (BackendConfig.Task t : m.tasks) { diff --git a/backend/src/main/java/com/example/backend/DeliveryVehicleServlet.java b/backend/src/main/java/com/example/backend/DeliveryVehicleServlet.java index e21e02e..7eb89cf 100644 --- a/backend/src/main/java/com/example/backend/DeliveryVehicleServlet.java +++ b/backend/src/main/java/com/example/backend/DeliveryVehicleServlet.java @@ -66,7 +66,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro return; } String vehicleId = request.getPathInfo().substring(1); - DeliveryVehicle vehicle = servletState.getDeliveryVehicleById(vehicleId); + DeliveryVehicle vehicle = servletState.getDeliveryVehicleById(deliveryService, vehicleId); if (vehicle != null) { ServletUtils.writeProtoJson(responseWriter, vehicle); } else { @@ -81,6 +81,8 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { + DeliveryServiceGrpc.DeliveryServiceBlockingStub deliveryService = + grpcServiceProvider.getAuthenticatedDeliveryService(); if (request.getPathInfo() == null) { logger.log( Level.WARNING, @@ -90,7 +92,7 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr } String vehicleId = request.getPathInfo().substring(1); - DeliveryVehicle vehicle = servletState.getDeliveryVehicleById(vehicleId); + DeliveryVehicle vehicle = servletState.getDeliveryVehicleById(deliveryService, vehicleId); if (vehicle == null) { logger.log( Level.WARNING, @@ -160,13 +162,9 @@ public void doPut(HttpServletRequest request, HttpServletResponse response) thro response.setCharacterEncoding("UTF-8"); PrintWriter responseWriter = response.getWriter(); - // As above, we're using the IP address to identify the client. - String clientIdentifier = request.getRemoteAddr(); - String vehicleId = request.getPathInfo().substring(1); DeliveryVehicle vehicle = - servletState.getDeliveryVehicleById( - servletState.getDeliveryVehicleMapByClient(clientIdentifier)); + servletState.getDeliveryVehicleById(deliveryService, vehicleId); if (vehicle == null) { logger.log(Level.WARNING, "The client is not assigned to any vehicle"); diff --git a/backend/src/main/java/com/example/backend/ManifestServlet.java b/backend/src/main/java/com/example/backend/ManifestServlet.java index 0940e65..a17d1b9 100644 --- a/backend/src/main/java/com/example/backend/ManifestServlet.java +++ b/backend/src/main/java/com/example/backend/ManifestServlet.java @@ -72,9 +72,10 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro return; } String vehicleId = request.getPathInfo().substring(1); - BackendConfig.Manifest manifest = servletState.getManifest(vehicleId); + String manifest = servletState.getManifestDS(vehicleId); if (manifest != null) { - responseWriter.print(BackendConfigGsonProvider.get().toJson(manifest)); + //responseWriter.print(BackendConfigGsonProvider.get().toJson(manifest)); + responseWriter.print(manifest); responseWriter.flush(); } else { logger.log( @@ -108,6 +109,8 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro */ @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { + DeliveryServiceGrpc.DeliveryServiceBlockingStub authenticatedDeliveryService = + grpcServiceProvider.getAuthenticatedDeliveryService(); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); PrintWriter responseWriter = response.getWriter(); @@ -167,20 +170,18 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr } logger.log(Level.INFO, String.format("clientId is %s", clientId)); try { - vehicle = assignVehicleToClient(clientId, vehicleId); + String assignedVehicleId = assignVehicleToClient(clientId, vehicleId); + String manifestJSON = servletState.getManifestDS(assignedVehicleId); + responseWriter.print(manifestJSON); } catch (ManifestException e) { logger.log(Level.WARNING, e.getLogMessage()); ServletUtils.setErrorResponse(response, e.getErrorMessage(), e.getErrorCode()); - return; } - BackendConfig.Manifest manifest = - servletState.getManifest(ServletState.getId(vehicle.getName())); - responseWriter.print(BackendConfigGsonProvider.get().toJson(manifest)); return; } // Otherwise, a vehicleId is required. - vehicle = servletState.getDeliveryVehicleById(vehicleId); + vehicle = servletState.getDeliveryVehicleById(authenticatedDeliveryService, vehicleId); if (vehicle == null) { logger.log( Level.WARNING, @@ -241,57 +242,28 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr * @return The assigned vehicle. * @throws ManifestException if the vehicle could not be assigned to the client. */ - private DeliveryVehicle assignVehicleToClient(String clientId, String vehicleId) + private String assignVehicleToClient(String clientId, String vehicleId) throws ManifestException { - // Assignment does not require a vehicleId; but if a vehicleId is supplied, attempt to use it. - String existingVehicleId = servletState.getDeliveryVehicleMapByClient(clientId); DeliveryVehicle vehicle; + String assignedVehicleId = vehicleId; - if (existingVehicleId != null) { - // If the client is already assigned another vehicle... - if (!vehicleId.equals("") && !vehicleId.equals(existingVehicleId)) { - throw new ManifestException( - "The client attempted to re-request another vehicle", - "You cannot request different vehicles.", - 403); - } - - vehicle = servletState.getDeliveryVehicleById(existingVehicleId); - if (vehicle == null) { + if (vehicleId.equals("")) { + assignedVehicleId = servletState.lookupAndAssignVehicle(clientId); + if (assignedVehicleId == null) { throw new ManifestException( - "The client\'s assigned vehicle doesn't exist.", - "The requested vehicle doesn't exist.", - 404); - } - } else if (vehicleId.equals("")) { - // If vehicleId is null, assign the next available vehicle - vehicle = servletState.getAnyAvailableDeliveryVehicle(); - if (vehicle == null) { - throw new ManifestException( - "The client requested a vehicle for assignment, but none were available.", + "The client requested a vehicle matching " + clientId + " for assignment, but none were available.", "There are no available vehicles for assignment.", 404); } + return assignedVehicleId; } else { - // If vehicleId is not null, attempt to assign that vehicle - vehicle = servletState.getDeliveryVehicleById(vehicleId); - if (vehicle == null) { + if (!servletState.isDeliveryVehicleAssigned(vehicleId)) { throw new ManifestException( - "The client attempted to request a non-existent vehicle", - "The requested vehicle doesn't exist.", - 404); - } - if (servletState.isDeliveryVehicleAssigned(vehicleId)) { - throw new ManifestException( - "The client attempted to request a vehicle that is currently assigned", - "The requested vehicle is currently assigned.", + "The client attempted to request a non-existent/assigned vehicle", "Invalid vehicleID", 403); } + return vehicleId; } - - // We have a vehicle available for assignment, or is already assigned to the same vehicle. - servletState.addClientToDeliveryVehicleMap(clientId, vehicle); - return vehicle; } /** @@ -304,6 +276,8 @@ private DeliveryVehicle assignVehicleToClient(String clientId, String vehicleId) */ private DeliveryVehicle updateVehicleStopState(DeliveryVehicle vehicle, String stopStateName) throws ManifestException { + String vehicleId = ServletState.getId(vehicle.getName()); + BackendConfig.Manifest manifest = servletState.getManifest(vehicleId); VehicleStop.State state; switch (stopStateName) { case "STATE_UNSPECIFIED": @@ -337,14 +311,14 @@ private DeliveryVehicle updateVehicleStopState(DeliveryVehicle vehicle, String s grpcServiceProvider.getAuthenticatedDeliveryService(); DeliveryVehicle responseVehicle = authenticatedDeliveryService.updateDeliveryVehicle(updateReq); servletState.addDeliveryVehicle(responseVehicle); - String vehicleId = ServletState.getId(vehicle.getName()); BackendConfig.StopState backendConfigStopState = BackendConfig.StopState.of(stopStateName); logger.log( Level.INFO, String.format( "updating manifest with vehicle ID %s and stop state %s", vehicleId, backendConfigStopState.getValue())); - servletState.getManifest(vehicleId).currentStopState = backendConfigStopState; + manifest.currentStopState = backendConfigStopState; + servletState.updateManifest(manifest); return responseVehicle; } @@ -397,6 +371,8 @@ private DeliveryVehicle updateVehicleStopList(DeliveryVehicle vehicle, List tasks; private HashMap deliveryVehicles; private HashMap clientToDeliveryVehicleMapping; + private DatastoreService datastore; public ServletState() { this.tasks = new HashMap<>(); this.deliveryVehicles = new HashMap<>(); this.clientToDeliveryVehicleMapping = new HashMap<>(); + this.datastore = DatastoreServiceFactory.getDatastoreService(); } /** Adds a delivery vehicle into the servlet state. */ public synchronized void addDeliveryVehicle(DeliveryVehicle deliveryVehicle) { - this.deliveryVehicles.put(getId(deliveryVehicle.getName()), deliveryVehicle); + //this.deliveryVehicles.put(getId(deliveryVehicle.getName()), deliveryVehicle); } /** Retrieves a delivery vehicle by ID. Null if vehicle ID doesn't match any vehicle. */ - public synchronized DeliveryVehicle getDeliveryVehicleById(String vehicleId) { - return deliveryVehicles.get(vehicleId); + public synchronized DeliveryVehicle getDeliveryVehicleById(DeliveryServiceGrpc.DeliveryServiceBlockingStub authenticatedDeliveryService, + String vehicleId) { + // TODO: need to prepend provide//... stuf + GetDeliveryVehicleRequest req = + GetDeliveryVehicleRequest.newBuilder().setName(VehicleUtils.getVehicleNameFromId(vehicleId)).build(); + return authenticatedDeliveryService.getDeliveryVehicle(req); } /** @@ -61,63 +86,129 @@ public synchronized DeliveryVehicle getDeliveryVehicleById(String vehicleId) { * overwritten. */ public synchronized void addTask(Task task) { - this.tasks.put(getId(task.getName()), task); + //this.tasks.put(getId(task.getName()), task); } /** Retrieves a task by ID. Null if task ID doesn't match any task. */ - public synchronized Task getTaskById(String taskId) { - return tasks.get(taskId); + public synchronized Task getTaskById(DeliveryServiceGrpc.DeliveryServiceBlockingStub authenticatedDeliveryService, String taskId) { + // Fetch the task from Fleet Engine, just in case. + GetTaskRequest req = + GetTaskRequest.newBuilder().setName(TaskUtils.getTaskNameFromId(taskId)).build(); + return authenticatedDeliveryService.getTask(req); } - /** - * Adds a client into the assignment list. The client is the courier servicing this set of tasks. - */ - public synchronized void addClientToDeliveryVehicleMap(String clientId, DeliveryVehicle vehicle) { - String vehicleId = getId(vehicle.getName()); - if (!isDeliveryVehicleAssigned(vehicleId)) { - clientToDeliveryVehicleMapping.put(clientId, vehicleId); - getManifest(vehicleId).clientId = clientId; - } + public synchronized String lookupAndAssignVehicle(String clientIdentifier) { + Query q = new Query("VehicleManifest") + .setFilter(new FilterPredicate("clientIdentifier", FilterOperator.EQUAL, clientIdentifier)); + PreparedQuery pq = datastore.prepare(q); + Entity vehicleManifest = pq.asSingleEntity(); + if (vehicleManifest != null) { + String vehicleId = vehicleManifest.getKey().getName(); + vehicleManifest.setProperty("assigned", true); + this.datastore.put(vehicleManifest); + return vehicleId; + } else { + return null; + } } /** Retrieves the vehicle mapped to a client. */ public synchronized String getDeliveryVehicleMapByClient(String clientIdentifier) { - return clientToDeliveryVehicleMapping.get(clientIdentifier); + Query q = new Query("VehicleManifest") + .setFilter(new FilterPredicate("clientIdentifier", FilterOperator.EQUAL, clientIdentifier)); + PreparedQuery pq = datastore.prepare(q); + Entity result = pq.asSingleEntity(); + if (result != null) { + return result.getKey().getName(); + } else { + return null; + } } /** Returns true if the vehicle is mapped to a client. */ public synchronized boolean isDeliveryVehicleAssigned(String vehicleId) { - return clientToDeliveryVehicleMapping.containsValue(vehicleId); + try { + Key vehicleManifestKey = KeyFactory.createKey("VehicleManifest", vehicleId); + Entity vehicleManifest = this.datastore.get(vehicleManifestKey); + // TODO: is this just really has a clientIdentifier set ... I think so + Boolean assigned = (Boolean)vehicleManifest.getProperty("assigned"); + return assigned; + } catch (EntityNotFoundException e) { + return false; + } + //return clientToDeliveryVehicleMapping.containsValue(vehicleId); } + /** Retrieves any available (unassigned) vehicle. If all vehicles are assigned, returns null. */ public synchronized DeliveryVehicle getAnyAvailableDeliveryVehicle() { + return null; + /* for (DeliveryVehicle vehicle : deliveryVehicles.values()) { if (!isDeliveryVehicleAssigned(getId(vehicle.getName()))) { return vehicle; } } return null; + */ } public synchronized void setBackendConfig(BackendConfig backendConfig) { this.backendConfig = backendConfig; + for (BackendConfig.Manifest manifest : backendConfig.manifests) { + logger.log(Level.INFO, String.format("got manifest for %s", manifest.vehicle.vehicleId)); + Entity vehicleManifest = new Entity("VehicleManifest", manifest.vehicle.vehicleId); + logger.log(Level.INFO, String.format("got key for %s", vehicleManifest.getKey().getName())); + vehicleManifest.setProperty("json", new Text(BackendConfigGsonProvider.get().toJson(manifest))); + vehicleManifest.setProperty("clientIdentifier", manifest.expectedClientId); + vehicleManifest.setProperty("assigned", false); + this.datastore.put(vehicleManifest); + } + } + + public synchronized void updateManifest(BackendConfig.Manifest m) { + String vehicleId = m.vehicle.vehicleId; + logger.log(Level.INFO, String.format("Setting manifest for %s", vehicleId)); + Key vehicleManifestKey = KeyFactory.createKey("VehicleManifest",vehicleId); + try { + Entity vehicleManifest = this.datastore.get(vehicleManifestKey); + vehicleManifest.setProperty("json", new Text(BackendConfigGsonProvider.get().toJson(m))); + this.datastore.put(vehicleManifest); + } catch (EntityNotFoundException e) { + logger.log(Level.WARNING, String.format("Failed to update manifest for %s", vehicleId)); + } } public synchronized BackendConfig.Manifest getManifest(String vehicleId) { logger.log(Level.INFO, String.format("getting manifest for %s", vehicleId)); - if (backendConfig == null) { - return null; + Key vehicleManifestKey = KeyFactory.createKey("VehicleManifest", vehicleId); + try { + Entity vehicleManifest = this.datastore.get(vehicleManifestKey); + if (vehicleManifest == null) { + logger.log(Level.INFO, String.format("no manifest found for %s", vehicleId)); + return null; + } + Text manifestJSON = (Text)vehicleManifest.getProperty("json"); + return BackendConfigGsonProvider.get().fromJson(manifestJSON.getValue(), BackendConfig.Manifest.class); + } catch (EntityNotFoundException e) { + return null; } - for (BackendConfig.Manifest manifest : backendConfig.manifests) { - if (manifest.vehicle.vehicleId.equals(vehicleId)) { - return manifest; - } + } + + public synchronized String getManifestDS(String vehicleId) { + logger.log(Level.INFO, String.format("getting manifest for %s", vehicleId)); + Key vehicleManifestKey = KeyFactory.createKey("VehicleManifest", vehicleId); + try { + Entity vehicleManifest = this.datastore.get(vehicleManifestKey); + Text manifestJSON = (Text)vehicleManifest.getProperty("json"); + return manifestJSON.getValue(); + } catch (EntityNotFoundException e) { + return null; } - return null; } public synchronized BackendConfig.Task getBackendConfigTask(String taskId) { + //TODO query database if (backendConfig == null) { return null; } @@ -131,14 +222,15 @@ public synchronized BackendConfig.Task getBackendConfigTask(String taskId) { return null; } - public synchronized void removeBackendConfigTask(String taskId) { - for (BackendConfig.Manifest manifest : backendConfig.manifests) { - for (BackendConfig.Stop stop : manifest.stops) { - ArrayList tasksList = new ArrayList<>(Arrays.asList(stop.tasks)); - tasksList.remove(taskId); - stop.tasks = tasksList.toArray(new String[tasksList.size()]); - } - } + public synchronized void removeBackendConfigTask(String vehicleId, String taskId) { + logger.log(Level.INFO, String.format("Removing task %s from vehicle for %s", taskId, vehicleId)); + BackendConfig.Manifest manifest = this.getManifest(vehicleId); + for (BackendConfig.Stop stop : manifest.stops) { + ArrayList tasksList = new ArrayList<>(Arrays.asList(stop.tasks)); + tasksList.remove(taskId); + stop.tasks = tasksList.toArray(new String[tasksList.size()]); + } + this.updateManifest(manifest); } /** diff --git a/backend/src/main/java/com/example/backend/TaskServlet.java b/backend/src/main/java/com/example/backend/TaskServlet.java index 1baf2ae..880dca4 100644 --- a/backend/src/main/java/com/example/backend/TaskServlet.java +++ b/backend/src/main/java/com/example/backend/TaskServlet.java @@ -79,7 +79,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro ServletUtils.setErrorResponse(response, "The vehicle ID must be specified.", 400); return; } - DeliveryVehicle vehicle = servletState.getDeliveryVehicleById(vehicleId); + DeliveryVehicle vehicle = servletState.getDeliveryVehicleById(authenticatedDeliveryService, vehicleId); ArrayList tasks = new ArrayList<>(); if (vehicle == null) { logger.log(Level.WARNING, "The client requested tasks for a non-existent vehicle."); @@ -94,7 +94,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro if (taskInfo.getTaskId().isEmpty()) { continue; } - Task task = servletState.getTaskById(taskInfo.getTaskId()); + Task task = servletState.getTaskById(authenticatedDeliveryService, taskInfo.getTaskId()); if (task == null) { continue; } @@ -148,7 +148,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro } } - Task task = servletState.getTaskById(taskId); + Task task = servletState.getTaskById(authenticatedDeliveryService, taskId); if (task == null) { logger.log( Level.WARNING, @@ -173,6 +173,8 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { + DeliveryServiceGrpc.DeliveryServiceBlockingStub authenticatedDeliveryService = + grpcServiceProvider.getAuthenticatedDeliveryService(); if (request.getPathInfo() == null) { logger.log(Level.WARNING, "The client requested a task update but did not supply a taskId."); ServletUtils.setErrorResponse(response, "The task ID must be specified.", 400); @@ -180,7 +182,7 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr } String taskId = request.getPathInfo().substring(1); - Task task = servletState.getTaskById(taskId); + Task task = servletState.getTaskById(authenticatedDeliveryService, taskId); if (task == null) { logger.log( Level.WARNING, @@ -227,14 +229,12 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr .setUpdateMask( FieldMask.newBuilder().addPaths("task_outcome").addPaths("task_outcome_time")) .build(); - DeliveryServiceGrpc.DeliveryServiceBlockingStub authenticatedDeliveryService = - grpcServiceProvider.getAuthenticatedDeliveryService(); Task responseTask = authenticatedDeliveryService.updateTask(updateReq); servletState.addTask(responseTask); // The task has been marked as complete; remove it from the manifest. if (!outcome.equals(Task.TaskOutcome.TASK_OUTCOME_UNSPECIFIED)) { - servletState.removeBackendConfigTask(taskId); + servletState.removeBackendConfigTask(servletState.getId(responseTask.getDeliveryVehicleId()), taskId); } response.setContentType("application/json"); @@ -245,6 +245,8 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr @Override public void doPut(HttpServletRequest request, HttpServletResponse response) throws IOException { + DeliveryServiceGrpc.DeliveryServiceBlockingStub authenticatedDeliveryService = + grpcServiceProvider.getAuthenticatedDeliveryService(); if (request.getServletPath().equals("/task")) { if (request.getPathInfo() == null) { logger.log( @@ -255,7 +257,7 @@ public void doPut(HttpServletRequest request, HttpServletResponse response) thro String taskId = request.getPathInfo().substring(1); // Verify that the task exists in servletState. - Task task = servletState.getTaskById(taskId); + Task task = servletState.getTaskById(authenticatedDeliveryService, taskId); if (task == null) { logger.log( @@ -284,8 +286,6 @@ public void doPut(HttpServletRequest request, HttpServletResponse response) thro .setTask(updatedTask) .setUpdateMask(FieldMask.newBuilder().addPaths("task_outcome")) .build(); - DeliveryServiceGrpc.DeliveryServiceBlockingStub authenticatedDeliveryService = - grpcServiceProvider.getAuthenticatedDeliveryService(); Task responseTask = authenticatedDeliveryService.updateTask(updateReq); servletState.addTask(responseTask); diff --git a/backend/src/main/java/com/example/backend/json/BackendConfig.java b/backend/src/main/java/com/example/backend/json/BackendConfig.java index 8133a6b..1ed0d05 100644 --- a/backend/src/main/java/com/example/backend/json/BackendConfig.java +++ b/backend/src/main/java/com/example/backend/json/BackendConfig.java @@ -60,6 +60,7 @@ public static StopState of(String name) { public static class Manifest { public Vehicle vehicle; + public String expectedClientId; public Task[] tasks; public Stop[] stops; diff --git a/backend/src/main/java/com/example/backend/utils/VehicleUtils.java b/backend/src/main/java/com/example/backend/utils/VehicleUtils.java new file mode 100644 index 0000000..c6ee280 --- /dev/null +++ b/backend/src/main/java/com/example/backend/utils/VehicleUtils.java @@ -0,0 +1,38 @@ +/* Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.backend.utils; + +public final class VehicleUtils { + public static final String BACKEND_NAME = + String.format("providers/%s", SampleBackendUtils.backendProperties.providerId()); + public static final String VEHICLE_NAME_FORMAT = BACKEND_NAME + "/deliveryVehicles/%s"; + + private VehicleUtils() {} + + public static String getVehicleNameFromId(String vehicleId) { + return String.format(VEHICLE_NAME_FORMAT, vehicleId); + } + + public static String getRawVehicleId(String vehicleId) { + // Assume vehicle ID has _ appended. Remove this and return the rest. + int lastUnderscoreIndex = vehicleId.lastIndexOf("_"); + + // There should be at least one character before the last underscore. Otherwise it's an error. + if (lastUnderscoreIndex < 1) { + return null; + } + return vehicleId.substring(0, lastUnderscoreIndex); + } +} diff --git a/backend/src/main/resources/config.properties b/backend/src/main/resources/config.properties index 1b59f5d..9b66bc9 100644 --- a/backend/src/main/resources/config.properties +++ b/backend/src/main/resources/config.properties @@ -1,10 +1,10 @@ fleetengine-address=fleetengine.googleapis.com:443 -provider-id=lmfs-field-day -server-service-account-email=server@lmfs-field-day.iam.gserviceaccount.com -driver-service-account-email=driver@lmfs-field-day.iam.gserviceaccount.com -consumer-service-account-email=consumer@lmfs-field-day.iam.gserviceaccount.com -fleet-reader-service-account-email=fleet-reader@lmfs-field-day.iam.gserviceaccount.com +-provider-id=*****UPDATE_WITH_PROJECT_ID***** +-server-service-account-email=*****UPDATE_WITH_SERVER_SERVICE_ACCOUNT_EMAIL***** +-driver-service-account-email=*****UPDATE_WITH_DRIVER_SERVICE_ACCOUNT_EMAIL***** +-consumer-service-account-email=*****UPDATE_WITH_CONSUMER_SERVICE_ACCOUNT_EMAIL***** +-fleet-reader-service-account-email=*****UPDATE_WITH_FLEET_READER_SERVICE_ACCOUNT_EMAIL***** # The following are configurations used by the JavaScript apps. -api-key=AIzaSyDVhAU-2_aYlkWWz54jx6CKG5TYScG2dAc -backend-host=http://localhost:8080 \ No newline at end of file +api-key=*****UPDATE_WITH_JS_API_KEY***** ++backend-host=http:// diff --git a/backend/src/main/webapp/WEB-INF/appengine-web.xml b/backend/src/main/webapp/WEB-INF/appengine-web.xml index 490b4a0..07e477c 100644 --- a/backend/src/main/webapp/WEB-INF/appengine-web.xml +++ b/backend/src/main/webapp/WEB-INF/appengine-web.xml @@ -16,6 +16,8 @@ java11 YOUR-APPID-HERE + true + F4 1