Exemple #1
0
  @RolesAllowed(Roles.OWNER)
  @DELETE
  @Path("/{stream_name}")
  @ApiOperation(value = "Delete a stream.", notes = "TBD")
  @ApiResponses(value = {@ApiResponse(code = 500, message = "Internal Server Error")})
  public ResponseMsg doDeleteStream(
      @PathParam("stream_name") String streamName,
      @QueryParam("start_time") String startTime,
      @QueryParam("end_time") String endTime)
      throws JsonProcessingException {

    String ownerName = securityContext.getUserPrincipal().getName();
    StreamDatabaseDriver db = null;
    try {
      db = DatabaseConnector.getStreamDatabase();
      db.deleteStream(ownerName, streamName, startTime, endTime);
    } catch (ClassNotFoundException | IOException | NamingException | SQLException e) {
      throw WebExceptionBuilder.buildInternalServerError(e);
    } catch (IllegalArgumentException e) {
      throw WebExceptionBuilder.buildBadRequest(e);
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }
    return new ResponseMsg("Succefully deleted stream (" + streamName + ").");
  }
Exemple #2
0
  @RolesAllowed({Roles.OWNER, Roles.CONSUMER})
  @GET
  @ApiOperation(value = "Get list of streams", notes = "TBD")
  @ApiResponses(value = {@ApiResponse(code = 500, message = "Internal Server Error")})
  public List<Stream> doGetAllStreams(
      @ApiParam(
              name = "stream_owner",
              value = "If null, get currently authenticated user's streams.")
          @QueryParam("stream_owner")
          String streamOwner)
      throws JsonProcessingException {

    if (streamOwner == null) {
      streamOwner = securityContext.getUserPrincipal().getName();
    }

    List<Stream> streams = null;
    StreamDatabaseDriver db = null;
    try {
      db = DatabaseConnector.getStreamDatabase();
      streams = db.getStreamList(streamOwner);
    } catch (SQLException | ClassNotFoundException | IOException | NamingException e) {
      throw WebExceptionBuilder.buildInternalServerError(e);
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }
    return streams;
  }
Exemple #3
0
 @RolesAllowed(Roles.OWNER)
 @POST
 @Consumes(MediaType.APPLICATION_JSON)
 @ApiOperation(value = "Create a new stream", notes = "TBD")
 @ApiResponses(value = {@ApiResponse(code = 500, message = "Internal Server Error")})
 public ResponseMsg doPostNewStream(@Valid Stream stream) throws JsonProcessingException {
   StreamDatabaseDriver db = null;
   String ownerName = securityContext.getUserPrincipal().getName();
   stream.setOwner(ownerName);
   try {
     db = DatabaseConnector.getStreamDatabase();
     db.createStream(stream);
   } catch (IOException | NamingException | SQLException | ClassNotFoundException e) {
     throw WebExceptionBuilder.buildInternalServerError(e);
   } catch (IllegalArgumentException e) {
     throw WebExceptionBuilder.buildBadRequest(e);
   } finally {
     if (db != null) {
       try {
         db.close();
       } catch (SQLException e) {
         e.printStackTrace();
       }
     }
   }
   return new ResponseMsg("Successfully created a new stream: " + stream.name);
 }
  private void bulkloadDummyStreamData(String streamOwner, DateTime day)
      throws ClassNotFoundException, SQLException, IOException, NamingException,
          NoSuchAlgorithmException {
    DateTime curTime = new DateTime(day);
    DateTime endTime = new DateTime(day.plusDays(1).minusMillis(1));

    // delete for the day
    StreamDatabaseDriver db = null;
    try {
      db = DatabaseConnector.getStreamDatabase();
      db.deleteStream(streamOwner, DUMMY_STREAM_NAME, fmt.print(curTime), fmt.print(endTime));
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }

    // generate a bulkload data
    StringBuilder sb = new StringBuilder();
    while (curTime.isBefore(endTime)) {
      sb.append(fmt.print(curTime));
      sb.append(",1\n");
      curTime = curTime.plusSeconds(DUMMY_STREAM_INTERVAL);
    }

    // perform bulkload
    String bulkloadData = sb.toString();
    try {
      db = DatabaseConnector.getStreamDatabase();
      db.bulkLoad(streamOwner, DUMMY_STREAM_NAME, bulkloadData);
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }
  }
Exemple #5
0
  @RolesAllowed(Roles.OWNER)
  @POST
  @Path("/{stream_name}")
  @Consumes(MediaType.APPLICATION_JSON)
  @ApiOperation(value = "Add a new tuple to the stream.", notes = "TBD")
  @ApiResponses(value = {@ApiResponse(code = 500, message = "Interval Server Error")})
  public ResponseMsg doPostStream(
      @PathParam("stream_name") String streamName,
      @ApiParam(
              name = "str_tuple",
              value =
                  "<pre>Usage:\n"
                      + "[ timestamp, 1st_channel, 2nd_channel, 3rd_channel, .. ]\n"
                      + "\n"
                      + "  e.g., [ \"2013-01-01 09:20:12.12345\", 12.4, 1.2, 5.5 ]\n"
                      + "  e.g., [ null, 12.4, 1.2, 5.5 ]\n"
                      + "\n"
                      + "Or,\n"
                      + "{ \"timestamp\": timestamp\n"
                      + "  \"tuple\": [ 1st_channel, 2nd_channel, 3rd_channel, .. ] }\n"
                      + "\n"
                      + "  e.g., { \"timestamp\": \"2013-01-01 09:20:12.12345\"\n"
                      + "          \"tuple\": [ 12.4, 1.2, 5.5 ] }\n"
                      + "  e.g., { \"timestamp\": null\n"
                      + "          \"tuple\": [ 12.4, 1.2, 5.5 ] }\n"
                      + "\n"
                      + "If timestamp is null, current server time will be used.</pre>")
          String strTuple)
      throws JsonProcessingException {

    String ownerName = securityContext.getUserPrincipal().getName();
    StreamDatabaseDriver db = null;
    try {
      db = DatabaseConnector.getStreamDatabase();
      db.addTuple(ownerName, streamName, strTuple);
    } catch (ClassNotFoundException | IOException | NamingException | SQLException e) {
      e.printStackTrace();
      throw WebExceptionBuilder.buildInternalServerError(e);
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
      throw WebExceptionBuilder.buildBadRequest(e);
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }
    return new ResponseMsg("Successfully added the tuple.");
  }
  private void sendEmailToOwner(String username, String reportIdxFileName) {
    String link = basePath + REPORTS_URL + "/" + reportIdxFileName;
    link = "<a href=\"" + link + "\">" + link + "</a>";

    String title =
        EMAIL_TITLE + " (" + titleFmt.print(startDate) + " ~ " + titleFmt.print(endDate) + ")";
    String body =
        "Your data reports are ready for your review at the following address:<br/><br/>" + link;
    body += "<br/><br/>Please access the above link and provide us your feedback!<br/><br/>";
    body += "Regards,<br/>SensorPrivacy Research Team";

    // Get email address
    UserDatabaseDriver db = null;
    String email = null;
    try {
      db = DatabaseConnector.getUserDatabase();
      email = db.getUserEmail(username);
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (SQLException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (NamingException e) {
      e.printStackTrace();
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }

    if (email == null) {
      Log.error("No email address for " + username);
      return;
    }

    try {
      MailSender.send(email, title, body);
    } catch (MessagingException e) {
      e.printStackTrace();
      Log.error("Error while sending email..");
      return;
    }

    Log.info("Done sending email!");
  }
Exemple #7
0
  @RolesAllowed(Roles.OWNER)
  @POST
  @Path("/{stream_name}.csv")
  @Consumes(MediaType.APPLICATION_OCTET_STREAM)
  @ApiOperation(value = "Load csv file to a stream.", notes = "TBD")
  @ApiResponses(value = {@ApiResponse(code = 500, message = "Interval Server Error")})
  public ResponseMsg doPostStreamCsv(
      @PathParam("stream_name") String streamName,
      @ApiParam(
              name = "str_tuple",
              value =
                  "<pre>Usage:\n"
                      + "timestamp, 1st_channel, 2nd_channel, 3rd_channel, ..\n"
                      + "timestamp, 1st_channel, 2nd_channel, 3rd_channel, ..\n"
                      + ".\n"
                      + ".\n"
                      + "\n"
                      + "e.g.,\n"
                      + "2013-01-01 09:20:12.12345, 12.4, 1.2, 5.5\n"
                      + "2013-01-01 09:20:13.12345, 11.4, 3.2, 1.5\n"
                      + "2013-01-01 09:20:14.12345, 10.4, 4.2, 7.5\n"
                      + "</pre>")
          String data)
      throws JsonProcessingException {

    String ownerName = securityContext.getUserPrincipal().getName();
    StreamDatabaseDriver db = null;
    try {
      db = DatabaseConnector.getStreamDatabase();
      db.bulkLoad(ownerName, streamName, data);
    } catch (SQLException
        | IOException
        | ClassNotFoundException
        | NamingException
        | NoSuchAlgorithmException e) {
      throw WebExceptionBuilder.buildInternalServerError(e);
    } catch (IllegalArgumentException e) {
      throw WebExceptionBuilder.buildBadRequest(e);
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }
    return new ResponseMsg("Successfully completed bulkloading.");
  }
 private void createDummyStream(String streamOwner)
     throws ClassNotFoundException, SQLException, IOException, NamingException {
   StreamDatabaseDriver db = null;
   Stream stream = new Stream();
   stream.setOwner(streamOwner);
   stream.name = DUMMY_STREAM_NAME;
   stream.tags = DUMMY_STREAM_NAME;
   stream.channels = new ArrayList<Channel>();
   stream.channels.add(new Channel(DUMMY_STREAM_CHANNEL_NAME, DUMMY_STREAM_CHANNEL_TYPE));
   try {
     db = DatabaseConnector.getStreamDatabase();
     db.createStream(stream);
   } finally {
     if (db != null) {
       try {
         db.close();
       } catch (SQLException e) {
         e.printStackTrace();
       }
     }
   }
 }
Exemple #9
0
 @RolesAllowed(Roles.OWNER)
 @DELETE
 @ApiOperation(value = "Delete entire streams.", notes = "TBD")
 @ApiResponses(value = {@ApiResponse(code = 500, message = "Internal Server Error")})
 public ResponseMsg doDeleteAllStreams() throws JsonProcessingException {
   String ownerName = securityContext.getUserPrincipal().getName();
   StreamDatabaseDriver db = null;
   try {
     db = DatabaseConnector.getStreamDatabase();
     db.deleteAllStreams(ownerName);
   } catch (SQLException | ClassNotFoundException | IOException | NamingException e) {
     throw WebExceptionBuilder.buildInternalServerError(e);
   } finally {
     if (db != null) {
       try {
         db.close();
       } catch (SQLException e) {
         e.printStackTrace();
       }
     }
   }
   return new ResponseMsg("Successfully deleted all streams.");
 }
Exemple #10
0
  @RolesAllowed({Roles.OWNER, Roles.CONSUMER})
  @GET
  @Path("/{stream_name}")
  @ApiOperation(value = "Retrieve the stream.", notes = GET_STREAM_NOTES)
  @ApiResponses(value = {@ApiResponse(code = 500, message = "Internal Server Error")})
  public Object doGetStream(
      @PathParam("stream_name") final String streamName,
      @ApiParam(
              name = "stream_owner",
              value = "If null, get currently authenticated user's streams.")
          @QueryParam("stream_owner")
          final String streamOwnerParam,
      @ApiParam(name = "start_time", value = "Expected format: YYYY-MM-DD HH:MM:SS.[SSSSS]")
          @QueryParam("start_time")
          final String startTime,
      @ApiParam(name = "end_time", value = "Expected format: YYYY-MM-DD HH:MM:SS.[SSSSS]")
          @QueryParam("end_time")
          final String endTime,
      @ApiParam(name = "filter", value = "Please refer to the above Implementation Notes.")
          @QueryParam("filter")
          final String filter,
      @ApiParam(name = "aggregator", value = "Please refer to the above Implementation Notes.")
          @QueryParam("aggregator")
          final String aggregator,
      @ApiParam(name = "limit", value = "Default value is 100.")
          @DefaultValue("100")
          @QueryParam("limit")
          final int limit,
      @ApiParam(name = "offset", value = "Default value is 0.") @QueryParam("offset")
          final int offset,
      @ApiParam(name = "http_streaming", value = "Default value is true.")
          @DefaultValue("false")
          @QueryParam("http_streaming")
          final boolean isHttpStreaming)
      throws JsonProcessingException {

    StreamDatabaseDriver db = null;
    final String requestingUser = securityContext.getUserPrincipal().getName();
    final String streamOwner = streamOwnerParam == null ? requestingUser : streamOwnerParam;
    try {
      db = DatabaseConnector.getStreamDatabase();
      if (!isHttpStreaming && limit > ROW_LIMIT_WITHOUT_HTTP_STREAMING) {
        throw WebExceptionBuilder.buildBadRequest(
            "Too mcuh data requested without HTTP streaming.");
      }

      if (!isHttpStreaming) {
        boolean isData =
            db.prepareQuery(
                requestingUser,
                streamOwner,
                streamName,
                startTime,
                endTime,
                aggregator,
                filter,
                limit,
                offset,
                0,
                false,
                null);
        String strJson = getStreamJsonPrefix(db.getStoredStreamInfo());
        if (isData) {
          Object[] tuple = db.getNextTuple();
          if (tuple != null) {
            strJson += convertTupleToJsonString(tuple);
            while ((tuple = db.getNextTuple()) != null) {
              strJson += "," + convertTupleToJsonString(tuple);
            }
          }
        }
        return strJson + "]}";
      } else {
        return new StreamingOutput() {
          @Override
          public void write(OutputStream output) throws IOException, WebApplicationException {
            StreamDatabaseDriver db = null;
            try {
              db = DatabaseConnector.getStreamDatabase();
              boolean isData =
                  db.prepareQuery(
                      requestingUser,
                      streamOwner,
                      streamName,
                      startTime,
                      endTime,
                      aggregator,
                      filter,
                      limit,
                      offset,
                      0,
                      false,
                      null);
              String strJson = getStreamJsonPrefix(db.getStoredStreamInfo());
              IOUtils.write(strJson, output);
              if (isData) {
                Object[] tuple = db.getNextTuple();
                if (tuple != null) {
                  IOUtils.write(convertTupleToJsonString(tuple), output);
                  while ((tuple = db.getNextTuple()) != null) {
                    IOUtils.write("," + convertTupleToJsonString(tuple), output);
                  }
                }
              }
              IOUtils.write("]}", output);
            } catch (SQLException
                | ClassNotFoundException
                | NamingException
                | UnsupportedOperationException e) {
              e.printStackTrace();
              throw WebExceptionBuilder.buildInternalServerError(e);
            } catch (IllegalArgumentException e) {
              e.printStackTrace();
              throw WebExceptionBuilder.buildBadRequest(e);
            } finally {
              if (db != null) {
                try {
                  db.close();
                } catch (SQLException e) {
                  e.printStackTrace();
                }
              }
            }
          }
        };
      }
    } catch (ClassNotFoundException
        | IOException
        | NamingException
        | SQLException
        | UnsupportedOperationException e) {
      e.printStackTrace();
      throw WebExceptionBuilder.buildInternalServerError(e);
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
      throw WebExceptionBuilder.buildBadRequest(e);
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }
  }
Exemple #11
0
  @RolesAllowed({Roles.OWNER, Roles.CONSUMER})
  @GET
  @Path("/{stream_name}.png")
  @Produces("image/png")
  @ApiOperation(value = "Retrieve the stream.", notes = GET_STREAM_NOTES)
  @ApiResponses(value = {@ApiResponse(code = 500, message = "Internal Server Error")})
  public Response doGetStreamAsPng(
      @PathParam("stream_name") final String streamName,
      @ApiParam(
              name = "stream_owner",
              value = "If null, get currently authenticated user's streams.")
          @QueryParam("stream_owner")
          final String streamOwnerParam,
      @ApiParam(name = "start_time", value = "Expected format: YYYY-MM-DD HH:MM:SS.[SSSSS]")
          @QueryParam("start_time")
          final String startTime,
      @ApiParam(name = "end_time", value = "Expected format: YYYY-MM-DD HH:MM:SS.[SSSSS]")
          @QueryParam("end_time")
          final String endTime,
      @ApiParam(name = "filter", value = "Please refer to the above Implementation Notes.")
          @QueryParam("filter")
          final String filter,
      @ApiParam(name = "aggregator", value = "Please refer to the above Implementation Notes.")
          @QueryParam("aggregator")
          String aggregator,
      /*@ApiParam(name = "limit", value = "Default value is 100.")
      @DefaultValue("100") @QueryParam("limit") 	final int limit,
      @ApiParam(name = "offset", value = "Default value is 0.")
      @QueryParam("offset") 						final int offset,*/
      @ApiParam(name = "width", value = "Chart width in pixels. Default is 500.")
          @DefaultValue("500")
          @QueryParam("width")
          int width,
      @ApiParam(name = "height", value = "Chart width in pixels. Default is 300.")
          @DefaultValue("300")
          @QueryParam("height")
          int height)
      throws IOException {

    StreamDatabaseDriver db = null;
    String requestingUser = securityContext.getUserPrincipal().getName();
    String streamOwner = streamOwnerParam == null ? requestingUser : streamOwnerParam;

    try {
      db = DatabaseConnector.getStreamDatabase();

      boolean isData =
          db.prepareQuery(
              requestingUser,
              streamOwner,
              streamName,
              startTime,
              endTime,
              aggregator,
              filter,
              0,
              0,
              0,
              true,
              null);
      Stream stream = db.getStoredStreamInfo();

      if (!isData) {
        return Response.ok("No data").build();
      }

      if (stream.num_samples > width) {
        db.close();
        db = DatabaseConnector.getStreamDatabase();
        int skipEveryNth = (int) (stream.num_samples / width);
        isData =
            db.prepareQuery(
                requestingUser,
                streamOwner,
                streamName,
                startTime,
                endTime,
                aggregator,
                filter,
                0,
                0,
                skipEveryNth,
                true,
                null);
        stream = db.getStoredStreamInfo();

        if (!isData) {
          return Response.ok("No data").build();
        }
      }

      // Prepare data
      XYSeries[] series = null;
      long minTsInterval = Long.MAX_VALUE; // to determine whether to use marker on the plot.
      long prevTimestamp = -1;
      Object[] tuple = new Object[db.getStoredStreamInfo().channels.size() + 1];
      while (db.getNextTuple(tuple)) {
        // Init XYSeries array
        if (series == null) {
          series = new XYSeries[tuple.length - 1];
          for (int i = 0; i < series.length; i++) {
            series[i] = new XYSeries(stream.channels.get(i).name);
          }
        }

        long timestamp = ((Long) tuple[0]).longValue();
        for (int i = 1; i < tuple.length; i++) {
          try {
            series[i - 1].add(timestamp, (Number) tuple[i]);
          } catch (ClassCastException e) {
            continue;
          }
        }

        long diff = timestamp - prevTimestamp;
        if (diff > 0 && diff < minTsInterval) {
          minTsInterval = diff;
        }

        prevTimestamp = timestamp;
      }

      XYSeriesCollection xyDataset = new XYSeriesCollection();
      for (XYSeries s : series) {
        xyDataset.addSeries(s);
      }

      // Generate title string
      long start = (long) series[0].getMinX();
      long end = (long) series[0].getMaxX();
      Timestamp startTimestamp = new Timestamp(start);
      Timestamp endTimestamp = new Timestamp(end);
      String title =
          stream.owner
              + ": "
              + stream.name
              + "\n"
              + startTimestamp.toString()
              + " ~ "
              + endTimestamp.toString();

      //  Create the chart object
      ValueAxis xAxis = new DateAxis("Time");
      // NumberAxis xAxis = new NumberAxis("");
      NumberAxis yAxis = new NumberAxis("Value");
      yAxis.setAutoRangeIncludesZero(false); // override default

      StandardXYItemRenderer renderer;
      long dataCount = (end - start) / minTsInterval;
      if (dataCount <= width) {
        renderer =
            new StandardXYItemRenderer(
                StandardXYItemRenderer.LINES + StandardXYItemRenderer.SHAPES);
      } else {
        renderer = new StandardXYItemRenderer(StandardXYItemRenderer.LINES);
      }
      // renderer.setShapesFilled(true);

      XYPlot plot = new XYPlot(xyDataset, xAxis, yAxis, renderer);
      JFreeChart chart =
          new JFreeChart(title, new Font(Font.SANS_SERIF, Font.BOLD, 12), plot, true);
      // JFreeChart chart = new JFreeChart(title, plot);
      chart.setBackgroundPaint(java.awt.Color.WHITE);

      ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection());
      String filename = ServletUtilities.saveChartAsPNG(chart, width, height, info, session);

      File imageFile = new File("/tmp/" + filename);
      byte[] imageData = FileUtils.readFileToByteArray(imageFile);
      imageFile.delete();

      // Send non-streamed
      // return Response.ok(imageData).build();

      // Send streamed
      return Response.ok(new ByteArrayInputStream(imageData)).build();
    } catch (ClassNotFoundException
        | IOException
        | NamingException
        | SQLException
        | UnsupportedOperationException e) {
      e.printStackTrace();
      throw WebExceptionBuilder.buildInternalServerError(e);
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
      throw WebExceptionBuilder.buildBadRequest(e);
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }
  }
Exemple #12
0
  @RolesAllowed(Roles.OWNER)
  @POST
  @Path("/{stream_name}.zip")
  @Consumes("application/zip")
  @ApiOperation(value = "Load zip file to a stream.", notes = "TBD")
  @ApiResponses(value = {@ApiResponse(code = 500, message = "Interval Server Error")})
  public ResponseMsg doPostStreamZip(
      @PathParam("stream_name") String streamName,
      @ApiParam(
              name = "str_tuple",
              value =
                  "<pre>Usage: attach a zip file containing a single file with the following content:\n"
                      + "timestamp, 1st_channel, 2nd_channel, 3rd_channel, ..\n"
                      + "timestamp, 1st_channel, 2nd_channel, 3rd_channel, ..\n"
                      + ".\n"
                      + ".\n"
                      + "\n"
                      + "e.g.,\n"
                      + "2013-01-01 09:20:12.12345, 12.4, 1.2, 5.5\n"
                      + "2013-01-01 09:20:13.12345, 11.4, 3.2, 1.5\n"
                      + "2013-01-01 09:20:14.12345, 10.4, 4.2, 7.5\n"
                      + "</pre>")
          byte[] data)
      throws JsonProcessingException {

    // check if report generation is ongoing.
    synchronized (CreateReportRunnable.reportLock) {
      File lockFile = new File(CreateReportRunnable.REPORT_LOCK_FILE);
      if (lockFile.exists()) {
        throw WebExceptionBuilder.buildBadRequest("Report creation job is running..");
      }
    }

    // Create temporary file
    DataOutputStream os = null;
    File file = null;
    String zipFileName = null;
    String unzipFolderName = null;
    try {
      unzipFolderName = TEMP_ZIP_FILE_PREFIX + newUUIDString();
      zipFileName = unzipFolderName + ".zip";
      file = new File(zipFileName);
      if (file.exists()) {
        file.delete();
      }
      file.createNewFile();

      os = new DataOutputStream(new FileOutputStream(file));
      os.write(data);
    } catch (IOException e) {
      deleteTempZipFiles(zipFileName, unzipFolderName);
      throw WebExceptionBuilder.buildInternalServerError(e);
    } finally {
      try {
        if (os != null) os.close();
      } catch (IOException e) {
        throw WebExceptionBuilder.buildInternalServerError(e);
      }
    }

    // Unzip the file.
    String unzippedFileName = null;
    try {
      unzippedFileName = unzip(zipFileName, unzipFolderName);
    } catch (IOException | UnsupportedOperationException e) {
      deleteTempZipFiles(zipFileName, unzipFolderName);
      throw WebExceptionBuilder.buildInternalServerError(e);
    }

    // Check unzipped filename
    if (unzippedFileName == null) {
      deleteTempZipFiles(zipFileName, unzipFolderName);
      throw WebExceptionBuilder.buildBadRequest("Problem with Zip file.");
    }

    // Read the file into memory.
    String unzippedData = null;
    try {
      unzippedData = readEntireFile(unzippedFileName);
    } catch (IOException e) {
      deleteTempZipFiles(zipFileName, unzipFolderName);
      throw WebExceptionBuilder.buildInternalServerError(e);
    }

    if (unzippedData.length() <= 0) {
      deleteTempZipFiles(zipFileName, unzipFolderName);
      throw WebExceptionBuilder.buildBadRequest("Empty data.");
    }

    // Pass unzipped data to database
    String ownerName = securityContext.getUserPrincipal().getName();
    StreamDatabaseDriver db = null;
    try {
      db = DatabaseConnector.getStreamDatabase();
      db.bulkLoad(ownerName, streamName, unzippedData);
    } catch (SQLException
        | IOException
        | ClassNotFoundException
        | NamingException
        | NoSuchAlgorithmException e) {
      throw WebExceptionBuilder.buildInternalServerError(e);
    } catch (IllegalArgumentException e) {
      throw WebExceptionBuilder.buildBadRequest(
          e.getClass().getSimpleName() + ": " + e.getMessage());
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }

      deleteTempZipFiles(zipFileName, unzipFolderName);
    }

    return new ResponseMsg("Successfully completed zip bulkloading.");
  }
  private void prepareDummyStream(String streamOwner, String streamName)
      throws ClassNotFoundException, SQLException, IOException, NamingException,
          NoSuchAlgorithmException {

    // Check if dummy stream exists
    List<Stream> streams = null;
    StreamDatabaseDriver db = null;
    try {
      db = DatabaseConnector.getStreamDatabase();
      streams = db.getStreamList(streamOwner);
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }

    boolean isFound = false;
    for (Stream stream : streams) {
      if (stream.name.equals(DUMMY_STREAM_NAME)) {
        isFound = true;
      }
    }

    if (!isFound) {
      createDummyStream(streamOwner);
    }

    // Check if dummy stream has desired amount of data on today.
    DateTime day = simpleFmt.parseDateTime(startDate.toString(simpleFmt));
    int targetNumSamples = MAX_SEC_A_DAY / DUMMY_STREAM_INTERVAL;

    while (day.isBefore(endDate)) {
      Log.info("current day: " + fmt.print(day));

      String startTime = fmt.print(day);
      String endTime = fmt.print(day.plusDays(1).minusMillis(1));
      try {
        db = DatabaseConnector.getStreamDatabase();

        boolean isData =
            db.prepareQuery(
                streamOwner,
                streamOwner,
                DUMMY_STREAM_NAME,
                startTime,
                endTime,
                null,
                null,
                0,
                0,
                0,
                true,
                null);
        Stream stream = db.getStoredStreamInfo();

        if (!isData) {
          Log.error("isData false");
          throw new UnsupportedOperationException("idData false.");
        }

        if (stream.num_samples != targetNumSamples) {
          Log.info("dummy stream is no good. Bulkloading dummy stream..");
          bulkloadDummyStreamData(streamOwner, day);
        } else {
          Log.info("dummy stream is good.");
        }
      } finally {
        if (db != null) {
          try {
            db.close();
          } catch (SQLException e) {
            e.printStackTrace();
          }
        }
      }

      day = day.plusDays(1);
    }
  }
 private int[] queryUsingDummyStreamAsOtherUser(String streamOwner, String streamName)
     throws ClassNotFoundException, SQLException, IOException, NamingException {
   StreamDatabaseDriver db = null;
   String startTime = fmt.print(startDate);
   String endTime = fmt.print(endDate.minusMillis(1));
   Log.info("startTime: " + startTime + ", endTime: " + endTime);
   long durationInSecs = (endDate.getMillis() / 1000) - (startDate.getMillis() / 1000);
   int size = (int) (durationInSecs / DUMMY_STREAM_INTERVAL);
   if (size <= 0) {
     size = 1;
   }
   int[] shareflags = new int[size];
   Log.info("size: " + (int) (durationInSecs / DUMMY_STREAM_INTERVAL));
   try {
     db = DatabaseConnector.getStreamDatabase();
     boolean isData =
         db.prepareQuery(
             OTHER_USER_NAME,
             streamOwner,
             DUMMY_STREAM_NAME,
             startTime,
             endTime,
             null,
             null,
             0,
             0,
             0,
             false,
             streamName);
     if (!isData) {
       Log.info("No data shared with " + OTHER_USER_NAME + " for " + streamName);
       return shareflags;
     }
     Object[] tuple = new Object[db.getStoredStreamInfo().channels.size() + 1];
     long todayMillis = startDate.getMillis();
     while (db.getNextTuple(tuple)) {
       long timestamp = (Long) tuple[0];
       // Log.info("timestamp: " + timestamp);
       int idx = (int) ((timestamp - todayMillis) / 1000 / DUMMY_STREAM_INTERVAL);
       if (idx >= size) {
         Log.error(
             "idx >= size, timestamp = "
                 + fmt.print(new DateTime(timestamp))
                 + ", idx = "
                 + idx
                 + ", size = "
                 + size);
       } else {
         shareflags[idx] = 1;
       }
     }
     return shareflags;
   } finally {
     if (db != null) {
       try {
         db.close();
       } catch (SQLException e) {
         e.printStackTrace();
       }
     }
   }
 }
  private File createPNG(
      String streamName,
      int width,
      int height,
      String outputPath,
      boolean isLine,
      boolean isShape) {

    StreamDatabaseDriver db = null;
    String requestingUser = owner;
    String streamOwner = owner;

    String startTime = fmt.print(startDate);
    String endTime = fmt.print(endDate);

    try {
      db = DatabaseConnector.getStreamDatabase();

      boolean isData =
          db.prepareQuery(
              requestingUser,
              streamOwner,
              streamName,
              startTime,
              endTime,
              null,
              null,
              0,
              0,
              0,
              true,
              null);
      Stream stream = db.getStoredStreamInfo();

      if (!isData) {
        Log.error("isData null");
        return null;
      }

      if (stream.num_samples > width) {
        db.close();
        db = DatabaseConnector.getStreamDatabase();
        int skipEveryNth = (int) (stream.num_samples / width);
        isData =
            db.prepareQuery(
                requestingUser,
                streamOwner,
                streamName,
                startTime,
                endTime,
                null,
                null,
                0,
                0,
                skipEveryNth,
                false,
                null);
        stream = db.getStoredStreamInfo();

        if (!isData) {
          Log.error("isData null");
          return null;
        }
      }

      // Prepare data
      XYSeries[] series = null;
      long minTsInterval = Long.MAX_VALUE; // to determine whether to use marker on the plot.
      long prevTimestamp = -1;
      Object[] tuple = new Object[db.getStoredStreamInfo().channels.size() + 1];
      while (db.getNextTuple(tuple)) {
        // Init XYSeries array
        if (series == null) {
          series = new XYSeries[tuple.length - 1];
          for (int i = 0; i < series.length; i++) {
            series[i] = new XYSeries(stream.channels.get(i).name);
          }
        }

        long timestamp = ((Long) tuple[0]).longValue();
        for (int i = 1; i < tuple.length; i++) {
          try {
            series[i - 1].add(timestamp, (Number) tuple[i]);
          } catch (ClassCastException e) {
            continue;
          }
        }

        long diff = timestamp - prevTimestamp;
        if (diff > 0 && diff < minTsInterval) {
          minTsInterval = diff;
        }

        prevTimestamp = timestamp;
      }

      db.close();
      db = null;

      if (series == null) {
        throw new UnsupportedOperationException("No data for " + streamName);
      }

      XYSeriesCollection xyDataset = new XYSeriesCollection();
      for (XYSeries s : series) {
        xyDataset.addSeries(s);
      }

      // Generate title string
      long start = (long) series[0].getMinX();
      long end = (long) series[0].getMaxX();
      Timestamp startTimestamp = new Timestamp(start);
      Timestamp endTimestamp = new Timestamp(end);
      String title =
          stream.owner
              + ": "
              + stream.name
              + "\n"
              + startTimestamp.toString()
              + " ~ "
              + endTimestamp.toString();

      //  Create the chart object
      DateAxis xAxis = new DateAxis("Time");
      xAxis.setDateFormatOverride(new SimpleDateFormat("hh:mm aa"));
      // NumberAxis xAxis = new NumberAxis("");
      long margin = (endDate.getMillis() - startDate.getMillis()) / 24;
      xAxis.setRange(
          new Date(startDate.getMillis() - margin), new Date(endDate.getMillis() + margin));

      NumberAxis yAxis = new NumberAxis("Value");
      yAxis.setAutoRangeIncludesZero(false); // override default

      if (streamName.equals(ACTIVITY_SENSOR)) {
        yAxis.setTickUnit(new NumberTickUnit(1.0));
        yAxis.setRange(0.0, 4.0);
      } else if (streamName.equals(STRESS_SENSOR)) {
        yAxis.setTickUnit(new NumberTickUnit(1.0));
        yAxis.setRange(0.0, 1.0);
      } else if (streamName.equals(CONVERSATION_SENSOR)) {
        yAxis.setTickUnit(new NumberTickUnit(1.0));
        yAxis.setRange(0.0, 2.0);
      }

      StandardXYItemRenderer renderer;
      // long dataCount = (end - start) / minTsInterval;
      // if (dataCount <= width) {
      //	renderer = new StandardXYItemRenderer(StandardXYItemRenderer.LINES +
      // StandardXYItemRenderer.SHAPES);
      // } else {
      //	renderer = new StandardXYItemRenderer(StandardXYItemRenderer.LINES);
      // }
      if (isLine && isShape) {
        renderer =
            new StandardXYItemRenderer(
                StandardXYItemRenderer.LINES + StandardXYItemRenderer.SHAPES);
      } else if (isLine && !isShape) {
        renderer = new StandardXYItemRenderer(StandardXYItemRenderer.LINES);
      } else if (!isLine && isShape) {
        renderer = new StandardXYItemRenderer(StandardXYItemRenderer.SHAPES);
      } else {
        renderer = new StandardXYItemRenderer(StandardXYItemRenderer.LINES);
      }
      // renderer.setShapesFilled(true);

      XYPlot plot = new XYPlot(xyDataset, xAxis, yAxis, renderer);
      JFreeChart chart =
          new JFreeChart(title, new Font(Font.SANS_SERIF, Font.BOLD, 12), plot, true);
      // JFreeChart chart = new JFreeChart(title, plot);
      chart.setBackgroundPaint(java.awt.Color.WHITE);
      chart.removeLegend();

      // Marker
      final Color c = new Color(255, 60, 24, 63);
      List<Range> markerRanges = getUnsharedRanges(streamOwner, streamName);

      for (Range range : markerRanges) {
        Marker marker =
            new IntervalMarker(
                range.startTimeInMillis,
                range.endTimeInMillis,
                c,
                new BasicStroke(2.0f),
                null,
                null,
                1.0f);
        plot.addDomainMarker(marker, Layer.BACKGROUND);
      }

      ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection());
      String filename = ServletUtilities.saveChartAsPNG(chart, width, height, info, null);

      File imageFile = new File("/tmp/" + filename);
      File toFile =
          new File(outputPath + "/" + streamName + "_" + fileFmt.print(startDate) + ".png");
      imageFile.renameTo(toFile);

      return toFile;

    } catch (ClassNotFoundException
        | IOException
        | NamingException
        | SQLException
        | UnsupportedOperationException e) {
      e.printStackTrace();
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }
    return null;
  }
  private boolean generateGPSInitScript() {

    StreamDatabaseDriver db = null;
    String requestingUser = owner;
    String streamOwner = owner;
    String startTime = fmt.print(startDate);
    String endTime = fmt.print(endDate);

    long startTimestamp = startDate.getMillis();

    try {
      db = DatabaseConnector.getStreamDatabase();

      boolean isData =
          db.prepareQuery(
              requestingUser,
              streamOwner,
              GPS_STREAM_NAME,
              startTime,
              endTime,
              null,
              null,
              0,
              0,
              0,
              true,
              null);

      if (!isData) {
        Log.error("No GPS data..");
        return false;
      }

      Stream stream = db.getStoredStreamInfo();
      long numSamples = stream.num_samples;

      if (numSamples <= 0) {
        Log.error("numSamples <= 0 on " + GPS_STREAM_NAME);
        return false;
      }

      Object[] tuple = new Object[db.getStoredStreamInfo().channels.size() + 1];
      int timestamp;
      Coord coords[] = new Coord[(int) numSamples];
      int idx = 0;
      while (db.getNextTuple(tuple)) {
        timestamp = (int) (((Long) tuple[0] - startTimestamp) / 1000);
        coords[idx] = new Coord(timestamp, (Double) tuple[1], (Double) tuple[2]);
        idx++;
      }

      List<Coord> clusteredCoords = gpsClustering(coords);

      // Generate all shared gps poitns.
      StringBuilder sb = new StringBuilder();
      for (Coord coord : clusteredCoords) {
        sb.append("gps[");
        sb.append(coord.timestampInSecs);
        sb.append("] = new google.maps.Marker({ position: new google.maps.LatLng(");
        sb.append(coord.lat);
        sb.append(", ");
        sb.append(coord.lon);
        sb.append("), icon: sharedCircle, draggable: false, map: null });\n");
      }

      mGPSSamplesAllShared = sb.toString();

      // Generate based on rule processing.
      List<Range> unsharedRanges = getUnsharedRanges(streamOwner, GPS_STREAM_NAME);
      sb = new StringBuilder();
      for (Coord coord : clusteredCoords) {
        sb.append("gps[");
        sb.append(coord.timestampInSecs);
        sb.append("] = new google.maps.Marker({ position: new google.maps.LatLng(");
        sb.append(coord.lat);
        sb.append(", ");
        sb.append(coord.lon);
        sb.append("), icon: ");
        if (isCoordUnshared(coord, unsharedRanges)) {
          sb.append("nonSharedCircle");
        } else {
          sb.append("sharedCircle");
        }
        sb.append(", draggable: false, map: null });\n");
      }

      mGPSSamplesSharingFlagged = sb.toString();

      return true;
    } catch (JsonProcessingException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (SQLException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (NamingException e) {
      e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }
    return false;
  }