public ResponseEntity receiveMessage()

in services/image-analysis/java/src/main/java/services/EventController.java [73:200]


  public ResponseEntity<String> receiveMessage(
    @RequestBody Map<String, Object> body, @RequestHeader Map<String, String> headers) throws IOException, InterruptedException, ExecutionException {

    // Validate the number of available processors
    logger.info("EventController: Active processors: " + Runtime.getRuntime().availableProcessors()); 

    System.out.println("Header elements");
    for (String field : requiredFields) {
      if (headers.get(field) == null) {
        String msg = String.format("Missing expected header: %s.", field);
        System.out.println(msg);
        return new ResponseEntity<String>(msg, HttpStatus.BAD_REQUEST);
      } else {
        System.out.println(field + " : " + headers.get(field));
      }
    }

    System.out.println("Body elements");
    for (String bodyField : body.keySet()) {
      System.out.println(bodyField + " : " + body.get(bodyField));
    }

    if (headers.get("ce-subject") == null) {
      String msg = "Missing expected header: ce-subject.";
      System.out.println(msg);
      return new ResponseEntity<String>(msg, HttpStatus.BAD_REQUEST);
    }

    String ceSubject = headers.get("ce-subject");
    String msg = "Detected change in Cloud Storage bucket: (ce-subject) : " + ceSubject;
    System.out.println(msg);

    String fileName = (String)body.get("name");
    String bucketName = (String)body.get("bucket");

    logger.info("New picture uploaded " + fileName);

    try (ImageAnnotatorClient vision = ImageAnnotatorClient.create()) {
        List<AnnotateImageRequest> requests = new ArrayList<>();
        
        ImageSource imageSource = ImageSource.newBuilder()
            .setGcsImageUri("gs://" + bucketName + "/" + fileName)
            .build();

        Image image = Image.newBuilder()
            .setSource(imageSource)
            .build();

        Feature featureLabel = Feature.newBuilder()
            .setType(Type.LABEL_DETECTION)
            .build();
        Feature featureImageProps = Feature.newBuilder()
            .setType(Type.IMAGE_PROPERTIES)
            .build();
        Feature featureSafeSearch = Feature.newBuilder()
            .setType(Type.SAFE_SEARCH_DETECTION)
            .build();
            
        AnnotateImageRequest request = AnnotateImageRequest.newBuilder()
            .addFeatures(featureLabel)
            .addFeatures(featureImageProps)
            .addFeatures(featureSafeSearch)
            .setImage(image)
            .build();
        
        requests.add(request);

        logger.info("Calling the Vision API...");
        BatchAnnotateImagesResponse result = vision.batchAnnotateImages(requests);
        List<AnnotateImageResponse> responses = result.getResponsesList();

        if (responses.size() == 0) {
            logger.info("No response received from Vision API.");
            return new ResponseEntity<String>(msg, HttpStatus.BAD_REQUEST);
        }

        AnnotateImageResponse response = responses.get(0);
        if (response.hasError()) {
            logger.info("Error: " + response.getError().getMessage());
            return new ResponseEntity<String>(msg, HttpStatus.BAD_REQUEST);
        }

        List<String> labels = response.getLabelAnnotationsList().stream()
            .map(annotation -> annotation.getDescription())
            .collect(Collectors.toList());
        logger.info("Annotations found:");
        for (String label: labels) {
            logger.info("- " + label);
        }

        String mainColor = "#FFFFFF";
        ImageProperties imgProps = response.getImagePropertiesAnnotation();
        if (imgProps.hasDominantColors()) {
            DominantColorsAnnotation colorsAnn = imgProps.getDominantColors();
            ColorInfo colorInfo = colorsAnn.getColors(0);

            mainColor = rgbHex(
                colorInfo.getColor().getRed(), 
                colorInfo.getColor().getGreen(), 
                colorInfo.getColor().getBlue());

            logger.info("Color: " + mainColor);
        }

        boolean isSafe = false;
        if (response.hasSafeSearchAnnotation()) {
            SafeSearchAnnotation safeSearch = response.getSafeSearchAnnotation();

            isSafe = Stream.of(
                safeSearch.getAdult(), safeSearch.getMedical(), safeSearch.getRacy(),
                safeSearch.getSpoof(), safeSearch.getViolence())
            .allMatch( likelihood -> 
                likelihood != Likelihood.LIKELY && likelihood != Likelihood.VERY_LIKELY
            );

            logger.info("Safe? " + isSafe);
        }

        // Saving result to Firestore
        if (isSafe) {
          ApiFuture<WriteResult> writeResult = eventService.storeImage(fileName, labels,
              mainColor);
          logger.info("Picture metadata saved in Firestore at " + writeResult.get().getUpdateTime());
        }
    }

    return new ResponseEntity<String>(msg, HttpStatus.OK);
  }