Пример #1
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);
 }
Пример #2
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 + ").");
  }
Пример #3
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.");
  }
Пример #4
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.");
  }
Пример #5
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;
  }
Пример #6
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.");
 }
Пример #7
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();
        }
      }
    }
  }
Пример #8
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();
        }
      }
    }
  }
Пример #9
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.");
  }