Example usage for org.apache.thrift TDeserializer deserialize

List of usage examples for org.apache.thrift TDeserializer deserialize

Introduction

In this page you can find the example usage for org.apache.thrift TDeserializer deserialize.

Prototype

public void deserialize(TBase base, byte[] bytes) throws TException 

Source Link

Document

Deserialize the Thrift object from a byte array.

Usage

From source file:io.warp10.script.functions.UNWRAP.java

License:Apache License

@Override
public Object apply(WarpScriptStack stack) throws WarpScriptException {
    Object top = stack.pop();/* ww  w.  j a v a  2  s .  co  m*/

    if (!(top instanceof String) && !(top instanceof byte[]) && !(top instanceof List)) {
        throw new WarpScriptException(getName() + " operates on a string or byte array or a list thereof.");
    }

    List<Object> inputs = new ArrayList<Object>();

    if (top instanceof String || top instanceof byte[]) {
        inputs.add(top);
    } else {
        for (Object o : (List) top) {
            if (!(o instanceof String) && !(o instanceof byte[])) {
                throw new WarpScriptException(
                        getName() + " operates on a string or byte array or a list thereof.");
            }
            inputs.add(o);
        }
    }

    List<Object> outputs = new ArrayList<Object>();

    for (Object s : inputs) {
        byte[] bytes = s instanceof String
                ? OrderPreservingBase64.decode(s.toString().getBytes(Charsets.US_ASCII))
                : (byte[]) s;

        TDeserializer deser = new TDeserializer(new TCompactProtocol.Factory());

        try {
            GTSWrapper wrapper = new GTSWrapper();

            deser.deserialize(wrapper, bytes);

            GeoTimeSerie gts = GTSWrapperHelper.fromGTSWrapperToGTS(wrapper, this.empty);

            outputs.add(gts);
        } catch (TException te) {
            throw new WarpScriptException(getName() + " failed to unwrap GTS.");
        }
    }

    if (!(top instanceof List)) {
        stack.push(outputs.get(0));
    } else {
        stack.push(outputs);
    }

    return stack;
}

From source file:io.warp10.script.functions.UNWRAPENCODER.java

License:Apache License

@Override
public Object apply(WarpScriptStack stack) throws WarpScriptException {
    Object top = stack.pop();//from   ww w .  j a  v  a  2s . co  m

    if (!(top instanceof String) && !(top instanceof byte[])) {
        throw new WarpScriptException(getName() + " operates on a string or byte array.");
    }

    byte[] bytes = top instanceof String
            ? OrderPreservingBase64.decode(top.toString().getBytes(Charsets.US_ASCII))
            : (byte[]) top;

    TDeserializer deser = new TDeserializer(new TCompactProtocol.Factory());

    try {
        GTSWrapper wrapper = new GTSWrapper();

        deser.deserialize(wrapper, bytes);

        GTSDecoder decoder = GTSWrapperHelper.fromGTSWrapperToGTSDecoder(wrapper);

        decoder.next();

        stack.push(decoder.getEncoder(true));
    } catch (TException te) {
        throw new WarpScriptException(getName() + " failed to unwrap encoder.", te);
    } catch (IOException ioe) {
        throw new WarpScriptException(getName() + " failed to unwrap encoder.", ioe);
    }

    return stack;
}

From source file:io.warp10.script.functions.UNWRAPSIZE.java

License:Apache License

@Override
public Object apply(WarpScriptStack stack) throws WarpScriptException {
    Object top = stack.pop();//from  w w  w  .  j av  a2  s . co  m

    if (!(top instanceof String) && !(top instanceof byte[]) && !(top instanceof List)) {
        throw new WarpScriptException(getName() + " operates on a string or byte array or a list thereof.");
    }

    List<Object> inputs = new ArrayList<Object>();

    if (top instanceof String || top instanceof byte[]) {
        inputs.add(top);
    } else {
        for (Object o : (List) top) {
            if (!(o instanceof String) && !(o instanceof byte[])) {
                throw new WarpScriptException(
                        getName() + " operates on a string or byte array or a list thereof.");
            }
            inputs.add(o);
        }
    }

    List<Object> outputs = new ArrayList<Object>();

    for (Object s : inputs) {
        byte[] bytes = s instanceof String
                ? OrderPreservingBase64.decode(s.toString().getBytes(Charsets.US_ASCII))
                : (byte[]) s;

        TDeserializer deser = new TDeserializer(new TCompactProtocol.Factory());

        try {
            GTSWrapper wrapper = new GTSWrapper();

            deser.deserialize(wrapper, bytes);

            outputs.add(wrapper.getCount());
        } catch (TException te) {
            throw new WarpScriptException(getName() + " failed to unwrap GTS.");
        }
    }

    if (!(top instanceof List)) {
        stack.push(outputs.get(0));
    } else {
        stack.push(outputs);
    }

    return stack;
}

From source file:io.warp10.script.HyperLogLogPlus.java

License:Apache License

public static HyperLogLogPlus fromBytes(byte[] bytes) throws IOException, ClassNotFoundException {

    TDeserializer deserializer = new TDeserializer(new TCompactProtocol.Factory());

    HyperLogLogPlusParameters params = new HyperLogLogPlusParameters();

    try {/*ww w  .  j  a v a 2s  .c  om*/
        deserializer.deserialize(params, bytes);
    } catch (TException te) {
        throw new IOException(te);
    }

    HyperLogLogPlus hllp = new HyperLogLogPlus();

    hllp.setInitTime(params.getInitTime());

    if (params.isSetKey()) {
        hllp.setKey(params.getKey());
    }

    // Read p
    hllp.p = params.getP();
    hllp.m = 1 << hllp.p;
    // Read p'
    hllp.pprime = params.getPprime();
    hllp.mprime = 1 << hllp.pprime;

    hllp._64minusp = 64 - hllp.p;
    hllp.pmask = (1L << hllp._64minusp) - 1;
    hllp._64minuspprime = 64 - hllp.pprime;
    hllp.ptopprimemask = ((1L << hllp._64minusp) - 1) ^ ((1L << hllp._64minuspprime) - 1);
    hllp.pprimemask = ((1L << hllp._64minuspprime) - 1);

    // Read the current mode
    hllp.format = params.isSparse() ? Format.SPARSE : Format.NORMAL;

    if (Format.SPARSE == hllp.format) {
        hllp.sparse_list_len = params.getSparseListLen();
        hllp.sparse_list = params.getSparseList();
        // Allocate tmp_set
        hllp.tmp_set = new int[(int) Math.ceil((hllp.m * 6) / 8)];
        hllp.tmp_set_idx = 0;
    } else {
        // Read the registers
        if (params.isGzipped()) {
            ByteArrayInputStream bais = new ByteArrayInputStream(params.getRegisters());
            GZIPInputStream gzis = new GZIPInputStream(bais);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            while (true) {
                int len = gzis.read(buf);

                if (len < 0) {
                    break;
                }
                baos.write(buf, 0, len);
            }
            gzis.close();
            hllp.M = baos.toByteArray();
        } else {
            hllp.M = params.getRegisters();
        }
    }

    return hllp;
}

From source file:io.warp10.script.ScriptRunnerConsumerFactory.java

License:Apache License

@Override
public Runnable getConsumer(final KafkaSynchronizedConsumerPool pool,
        final KafkaStream<byte[], byte[]> stream) {

    return new Runnable() {
        @Override/*from ww w  . j  a v  a2s .  co  m*/
        public void run() {
            ConsumerIterator<byte[], byte[]> iter = stream.iterator();

            // Iterate on the messages
            TDeserializer deserializer = new TDeserializer(new TCompactProtocol.Factory());

            KafkaOffsetCounters counters = pool.getCounters();

            try {
                while (iter.hasNext()) {
                    //
                    // Since the call to 'next' may block, we need to first
                    // check that there is a message available
                    //

                    boolean nonEmpty = iter.nonEmpty();

                    if (nonEmpty) {
                        MessageAndMetadata<byte[], byte[]> msg = iter.next();
                        counters.count(msg.partition(), msg.offset());

                        byte[] data = msg.message();

                        Sensision.update(SensisionConstants.SENSISION_CLASS_WARP_RUNNER_KAFKA_IN_MESSAGES,
                                Sensision.EMPTY_LABELS, 1);
                        Sensision.update(SensisionConstants.SENSISION_CLASS_WARP_RUNNER_KAFKA_IN_BYTES,
                                Sensision.EMPTY_LABELS, data.length);

                        if (null != runner.KAFKA_MAC) {
                            data = CryptoUtils.removeMAC(runner.KAFKA_MAC, data);
                        }

                        // Skip data whose MAC was not verified successfully
                        if (null == data) {
                            Sensision.update(
                                    SensisionConstants.SENSISION_CLASS_WARP_RUNNER_KAFKA_IN_INVALIDMACS,
                                    Sensision.EMPTY_LABELS, 1);
                            continue;
                        }

                        // Unwrap data if need be
                        if (null != runner.KAFKA_AES) {
                            data = CryptoUtils.unwrap(runner.KAFKA_AES, data);
                        }

                        // Skip data that was not unwrapped successfuly
                        if (null == data) {
                            Sensision.update(
                                    SensisionConstants.SENSISION_CLASS_WARP_RUNNER_KAFKA_IN_INVALIDCIPHERS,
                                    Sensision.EMPTY_LABELS, 1);
                            continue;
                        }

                        final RunRequest request = new RunRequest();

                        deserializer.deserialize(request, data);

                        //
                        // Check if running is overdue
                        //

                        long now = System.currentTimeMillis();

                        if (request.getScheduledAt() + request.getPeriodicity() >= now) {
                            continue;
                        }

                        //
                        // Decompress script if it is compressed
                        //

                        if (request.isCompressed()) {
                            ByteArrayOutputStream out = new ByteArrayOutputStream();
                            GZIPInputStream in = new GZIPInputStream(
                                    new ByteArrayInputStream(request.getContent()));

                            byte[] buf = new byte[8192];

                            while (true) {
                                int len = in.read(buf);

                                if (len <= 0) {
                                    break;
                                }

                                out.write(buf, 0, len);
                            }

                            in.close();
                            out.close();

                            request.setContent(out.toByteArray());
                        }

                        //
                        // Submit script for execution, do up to 3 attempts
                        //

                        int attempts = 3;

                        while (attempts > 0) {
                            try {
                                runner.executor.submit(new Runnable() {
                                    @Override
                                    public void run() {

                                        Sensision.update(
                                                SensisionConstants.SENSISION_CLASS_EINSTEIN_RUN_CURRENT,
                                                Sensision.EMPTY_LABELS, 1);

                                        Map<String, String> labels = new HashMap<String, String>();
                                        labels.put(SensisionConstants.SENSISION_LABEL_PATH, request.getPath());

                                        Sensision.update(SensisionConstants.SENSISION_CLASS_EINSTEIN_RUN_COUNT,
                                                labels, 1);

                                        long nano = System.nanoTime();

                                        HttpURLConnection conn = null;

                                        long ops = 0;
                                        long fetched = 0;
                                        long elapsed = 0;

                                        try {
                                            conn = (HttpURLConnection) new URL(runner.endpoint)
                                                    .openConnection();

                                            conn.setDoOutput(true);
                                            conn.setChunkedStreamingMode(8192);
                                            conn.setDoInput(true);
                                            conn.setRequestMethod("POST");

                                            conn.connect();

                                            OutputStream out = conn.getOutputStream();

                                            //
                                            // Push the script parameters
                                            //

                                            out.write(Long.toString(request.getPeriodicity())
                                                    .getBytes(Charsets.UTF_8));
                                            out.write(' ');
                                            out.write('\'');
                                            out.write(URLEncoder.encode(Constants.RUNNER_PERIODICITY, "UTF-8")
                                                    .replaceAll("\\+", "%20").getBytes(Charsets.US_ASCII));
                                            out.write('\'');
                                            out.write(' ');
                                            out.write(WarpScriptLib.STORE.getBytes(Charsets.UTF_8));
                                            out.write('\n');

                                            out.write('\'');
                                            out.write(URLEncoder.encode(request.getPath(), "UTF-8")
                                                    .replaceAll("\\+", "%20").getBytes(Charsets.US_ASCII));
                                            out.write('\'');
                                            out.write(' ');
                                            out.write('\'');
                                            out.write(URLEncoder.encode(Constants.RUNNER_PATH, "UTF-8")
                                                    .replaceAll("\\+", "%20").getBytes(Charsets.US_ASCII));
                                            out.write('\'');
                                            out.write(' ');
                                            out.write(WarpScriptLib.STORE.getBytes(Charsets.UTF_8));
                                            out.write('\n');

                                            out.write(Long.toString(request.getScheduledAt())
                                                    .getBytes(Charsets.UTF_8));
                                            out.write(' ');
                                            out.write('\'');
                                            out.write(URLEncoder.encode(Constants.RUNNER_SCHEDULEDAT, "UTF-8")
                                                    .replaceAll("\\+", "%20").getBytes(Charsets.US_ASCII));
                                            out.write('\'');
                                            out.write(' ');
                                            out.write(WarpScriptLib.STORE.getBytes(Charsets.UTF_8));
                                            out.write('\n');

                                            byte[] data = request.getContent();

                                            if (request.isCompressed()) {
                                                ByteArrayInputStream bais = new ByteArrayInputStream(data);
                                                GZIPInputStream gzis = new GZIPInputStream(bais);
                                                byte[] buf = new byte[1024];

                                                while (true) {
                                                    int len = bais.read(buf);

                                                    if (len < 0) {
                                                        break;
                                                    }

                                                    out.write(buf, 0, len);
                                                }

                                                gzis.close();
                                            } else {
                                                out.write(data, 0, data.length);
                                            }

                                            // Add a 'CLEAR' at the end of the script so we don't return anything
                                            out.write(runner.CLEAR);

                                            out.close();

                                            if (200 != conn.getResponseCode()) {
                                                Sensision.update(
                                                        SensisionConstants.SENSISION_CLASS_EINSTEIN_RUN_FAILURES,
                                                        labels, 1);
                                            }

                                            String header = conn.getRequestProperty(
                                                    Constants.getHeader(Configuration.HTTP_HEADER_ELAPSEDX));
                                            if (null != header) {
                                                try {
                                                    elapsed = Long.parseLong(header);
                                                } catch (Exception e) {
                                                }
                                            }
                                            header = conn.getRequestProperty(
                                                    Constants.getHeader(Configuration.HTTP_HEADER_OPSX));
                                            if (null != header) {
                                                try {
                                                    ops = Long.parseLong(header);
                                                } catch (Exception e) {
                                                }
                                            }
                                            header = conn.getRequestProperty(
                                                    Constants.getHeader(Configuration.HTTP_HEADER_FETCHEDX));
                                            if (null != header) {
                                                try {
                                                    fetched = Long.parseLong(header);
                                                } catch (Exception e) {
                                                }
                                            }

                                        } catch (Exception e) {
                                            Sensision.update(
                                                    SensisionConstants.SENSISION_CLASS_EINSTEIN_RUN_FAILURES,
                                                    labels, 1);
                                        } finally {
                                            nano = System.nanoTime() - nano;
                                            Sensision.update(
                                                    SensisionConstants.SENSISION_CLASS_EINSTEIN_RUN_TIME_US,
                                                    labels, (long) (nano / 1000L));
                                            Sensision.update(
                                                    SensisionConstants.SENSISION_CLASS_EINSTEIN_RUN_ELAPSED,
                                                    labels, elapsed);
                                            Sensision.update(
                                                    SensisionConstants.SENSISION_CLASS_EINSTEIN_RUN_FETCHED,
                                                    labels, fetched);
                                            Sensision.update(
                                                    SensisionConstants.SENSISION_CLASS_EINSTEIN_RUN_OPS, labels,
                                                    ops);
                                            Sensision.update(
                                                    SensisionConstants.SENSISION_CLASS_EINSTEIN_RUN_CURRENT,
                                                    Sensision.EMPTY_LABELS, -1);
                                            if (null != conn) {
                                                conn.disconnect();
                                            }
                                        }
                                    }
                                });
                                break;
                            } catch (RejectedExecutionException ree) {
                                // Reschedule script immediately
                                Sensision.update(SensisionConstants.SENSISION_CLASS_WARP_RUNNER_REJECTIONS,
                                        Sensision.EMPTY_LABELS, 1);
                                attempts--;
                            }
                        }

                        if (0 == attempts) {
                            Sensision.update(SensisionConstants.SENSISION_CLASS_WARP_RUNNER_FAILURES,
                                    Sensision.EMPTY_LABELS, 1);
                        }
                    }
                }
            } catch (Throwable t) {
                t.printStackTrace(System.err);
            } finally {
                // Set abort to true in case we exit the 'run' method
                pool.getAbort().set(true);
            }
        }
    };
}

From source file:io.warp10.standalone.Migrate.java

License:Apache License

public static void main(String[] args) throws Exception {
    ///*from ww w  .  j a va  2 s . c  o m*/
    // Initialize keys
    //

    byte[] metaKey = Hex.decode("1111111111111111111111111111111111111111111111111111111111111111");
    byte[] classIdKey = Hex.decode("88888888888888888888888888888888");
    byte[] labelsIdKey = Hex.decode("99999999999999999999999999999999");

    String INDB = "/var/tmp/continuum-orig";
    String OUTDB = "/var/tmp/continuum-converted";

    //
    // Open source/target DBs
    //

    Options options = new Options();
    options.createIfMissing(true);
    options.cacheSize(100000000L);
    options.compressionType(CompressionType.SNAPPY);

    DB indb;

    try {
        indb = JniDBFactory.factory.open(new File(INDB), options);
    } catch (UnsatisfiedLinkError ule) {
        System.out.println("WARNING: falling back to pure java implementation of LevelDB.");
        indb = Iq80DBFactory.factory.open(new File(INDB), options);
    }

    DB outdb;

    try {
        outdb = JniDBFactory.factory.open(new File(OUTDB), options);
    } catch (UnsatisfiedLinkError ule) {
        System.out.println("WARNING: falling back to pure java implementation of LevelDB.");
        outdb = Iq80DBFactory.factory.open(new File(OUTDB), options);
    }

    //
    // Read/Update metadata
    //

    DBIterator iter = indb.iterator();

    // Seek start of metadata
    iter.seek("M".getBytes("UTF-8"));

    Map<BigInteger, byte[]> metadatas = new HashMap<BigInteger, byte[]>();

    TDeserializer deserializer = new TDeserializer(new TCompactProtocol.Factory());
    TSerializer serializer = new TSerializer(new TCompactProtocol.Factory());

    long nmeta = 0;

    long nano = System.nanoTime();

    while (iter.hasNext()) {
        Entry<byte[], byte[]> entry = iter.next();

        // Exit when done with metadata
        if (entry.getKey()[0] != 'M') {
            break;
        }

        byte[] clslblids = Arrays.copyOfRange(entry.getKey(), 1, 17);

        BigInteger bi = new BigInteger(clslblids);

        Metadata metadata = new Metadata();

        deserializer.deserialize(metadata, CryptoUtils.unwrap(metaKey, entry.getValue()));

        //
        // Compute new class/labels id
        //

        metadata.setClassId(GTSHelper.classId(classIdKey, metadata.getName()));
        metadata.setLabelsId(GTSHelper.labelsId(labelsIdKey, metadata.getLabels()));

        byte[] value = CryptoUtils.wrap(metaKey, serializer.serialize(metadata));
        byte[] key = new byte[17];

        ByteBuffer bb = ByteBuffer.wrap(key).order(ByteOrder.BIG_ENDIAN);
        bb.put((byte) 'M');
        bb.putLong(metadata.getClassId());
        bb.putLong(metadata.getLabelsId());

        outdb.put(key, value);

        metadatas.put(bi, Arrays.copyOfRange(key, 1, 17));
        nmeta++;
    }

    System.out
            .println("Updated " + nmeta + " metadatas in " + ((System.nanoTime() - nano) / 1000000.0D) + " ms");

    //
    // Read/Store readings
    //

    iter.seek("R".getBytes("UTF-8"));

    long ndata = 0;

    nano = System.nanoTime();

    while (iter.hasNext()) {
        Entry<byte[], byte[]> entry = iter.next();

        if (entry.getKey()[0] != 'R') {
            break;
        }

        byte[] clslblids = Arrays.copyOfRange(entry.getKey(), 1, 17);

        BigInteger bi = new BigInteger(clslblids);

        if (!metadatas.containsKey(bi)) {
            System.out.println("No metadata found for " + new String(Hex.encode(entry.getKey())));
            continue;
        }

        byte[] newkey = Arrays.copyOf(entry.getKey(), entry.getKey().length);
        System.arraycopy(metadatas.get(bi), 0, newkey, 1, 16);

        outdb.put(newkey, entry.getValue());

        ndata++;
    }

    System.out
            .println("Updated " + ndata + " readings in " + ((System.nanoTime() - nano) / 1000000.0D) + " ms");

    indb.close();
    outdb.close();
}

From source file:io.warp10.standalone.StandaloneChunkedMemoryStore.java

License:Apache License

private void load(String path) throws IOException {

    long nano = System.nanoTime();
    int gts = 0;//w  w w.j  ava2s.c o m
    long bytes = 0L;

    Configuration conf = new Configuration();

    conf.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
    conf.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName());

    BytesWritable key = new BytesWritable();
    BytesWritable value = new BytesWritable();

    TDeserializer deserializer = new TDeserializer(new TCompactProtocol.Factory());

    SequenceFile.Reader.Option optPath = SequenceFile.Reader.file(new Path(path));

    SequenceFile.Reader reader = null;

    boolean failsafe = "true".equals(
            properties.getProperty(io.warp10.continuum.Configuration.STANDALONE_MEMORY_STORE_LOAD_FAILSAFE));

    try {
        reader = new SequenceFile.Reader(conf, optPath);

        System.out.println("Loading '" + path + "' back in memory.");

        while (reader.next(key, value)) {
            gts++;
            GTSWrapper wrapper = new GTSWrapper();
            deserializer.deserialize(wrapper, key.copyBytes());
            GTSEncoder encoder = new GTSEncoder(0L, null, value.copyBytes());
            encoder.setCount(wrapper.getCount());

            bytes += value.getLength() + key.getLength();
            encoder.safeSetMetadata(wrapper.getMetadata());
            store(encoder);
            if (null != this.directoryClient) {
                this.directoryClient.register(wrapper.getMetadata());
            }
        }
    } catch (FileNotFoundException fnfe) {
        System.err.println("File '" + path + "' was not found, skipping.");
        return;
    } catch (IOException ioe) {
        if (!failsafe) {
            throw ioe;
        } else {
            System.err.println("Ignoring exception " + ioe.getMessage() + ".");
        }
    } catch (Exception e) {
        if (!failsafe) {
            throw new IOException(e);
        } else {
            System.err.println("Ignoring exception " + e.getMessage() + ".");
        }
    }

    reader.close();

    nano = System.nanoTime() - nano;

    System.out.println("Loaded " + gts + " GTS (" + bytes + " bytes) in " + (nano / 1000000.0D) + " ms.");
}

From source file:io.warp10.standalone.StandaloneDeleteHandler.java

License:Apache License

@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
    if (target.equals(Constants.API_ENDPOINT_DELETE)) {
        baseRequest.setHandled(true);/*from   w w w  . ja  va2 s  .  co  m*/
    } else {
        return;
    }

    //
    // CORS header
    //

    response.setHeader("Access-Control-Allow-Origin", "*");

    long nano = System.nanoTime();

    //
    // Extract DatalogRequest if specified
    //

    String datalogHeader = request.getHeader(Constants.getHeader(Configuration.HTTP_HEADER_DATALOG));

    DatalogRequest dr = null;

    boolean forwarded = false;

    if (null != datalogHeader) {
        byte[] bytes = OrderPreservingBase64.decode(datalogHeader.getBytes(Charsets.US_ASCII));

        if (null != datalogPSK) {
            bytes = CryptoUtils.unwrap(datalogPSK, bytes);
        }

        if (null == bytes) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Invalid Datalog header.");
            return;
        }

        TDeserializer deser = new TDeserializer(new TCompactProtocol.Factory());

        try {
            dr = new DatalogRequest();
            deser.deserialize(dr, bytes);
        } catch (TException te) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, te.getMessage());
            return;
        }

        Map<String, String> labels = new HashMap<String, String>();
        labels.put(SensisionConstants.SENSISION_LABEL_ID, new String(
                OrderPreservingBase64.decode(dr.getId().getBytes(Charsets.US_ASCII)), Charsets.UTF_8));
        labels.put(SensisionConstants.SENSISION_LABEL_TYPE, dr.getType());
        Sensision.update(SensisionConstants.CLASS_WARP_DATALOG_REQUESTS_RECEIVED, labels, 1);

        //
        // Check that the request query string matches the QS in the datalog request
        //

        if (!request.getQueryString().equals(dr.getDeleteQueryString())) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Invalid DatalogRequest.");
            return;
        }

        forwarded = true;
    }

    //
    // TODO(hbs): Extract producer/owner from token
    //

    String token = null != dr ? dr.getToken()
            : request.getHeader(Constants.getHeader(Configuration.HTTP_HEADER_TOKENX));

    if (null == token) {
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Missing token.");
        return;
    }

    WriteToken writeToken;

    try {
        writeToken = Tokens.extractWriteToken(token);
    } catch (WarpScriptException ee) {
        ee.printStackTrace();
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ee.getMessage());
        return;
    }

    String application = writeToken.getAppName();
    String producer = Tokens.getUUID(writeToken.getProducerId());
    String owner = Tokens.getUUID(writeToken.getOwnerId());

    //
    // For delete operations, producer and owner MUST be equal
    //

    if (!producer.equals(owner)) {
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Invalid write token for deletion.");
        return;
    }

    Map<String, String> sensisionLabels = new HashMap<String, String>();
    sensisionLabels.put(SensisionConstants.SENSISION_LABEL_PRODUCER, producer);

    long count = 0;
    long gts = 0;

    Throwable t = null;
    StringBuilder metas = new StringBuilder();
    // Boolean indicating whether or not we should continue adding results to 'metas'
    boolean metasSaturated = false;

    //
    // Extract start/end
    //

    String startstr = request.getParameter(Constants.HTTP_PARAM_START);
    String endstr = request.getParameter(Constants.HTTP_PARAM_END);

    //
    // Extract selector
    //

    String selector = request.getParameter(Constants.HTTP_PARAM_SELECTOR);

    String minage = request.getParameter(Constants.HTTP_PARAM_MINAGE);

    if (null != minage) {
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                "Standalone version does not support the '" + Constants.HTTP_PARAM_MINAGE
                        + "' parameter in delete requests.");
        return;
    }

    boolean dryrun = null != request.getParameter(Constants.HTTP_PARAM_DRYRUN);

    File loggingFile = null;
    PrintWriter loggingWriter = null;

    //
    // Open the logging file if logging is enabled
    //

    if (null != loggingDir) {
        long nanos = null != dr ? dr.getTimestamp() : TimeSource.getNanoTime();
        StringBuilder sb = new StringBuilder();
        sb.append(Long.toHexString(nanos));
        sb.insert(0, "0000000000000000", 0, 16 - sb.length());
        sb.append("-");
        if (null != dr) {
            sb.append(dr.getId());
        } else {
            sb.append(datalogId);
        }

        sb.append("-");
        sb.append(dtf.print(nanos / 1000000L));
        sb.append(Long.toString(1000000L + (nanos % 1000000L)).substring(1));
        sb.append("Z");

        if (null == dr) {
            dr = new DatalogRequest();
            dr.setTimestamp(nanos);
            dr.setType(Constants.DATALOG_DELETE);
            dr.setId(datalogId);
            dr.setToken(token);
            dr.setDeleteQueryString(request.getQueryString());
        }

        if (null != dr && (!forwarded || (forwarded && this.logforwarded))) {
            //
            // Serialize the request
            //

            TSerializer ser = new TSerializer(new TCompactProtocol.Factory());

            byte[] encoded;

            try {
                encoded = ser.serialize(dr);
            } catch (TException te) {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, te.getMessage());
                return;
            }

            if (null != this.datalogPSK) {
                encoded = CryptoUtils.wrap(this.datalogPSK, encoded);
            }

            encoded = OrderPreservingBase64.encode(encoded);

            loggingFile = new File(loggingDir, sb.toString());
            loggingWriter = new PrintWriter(new FileWriterWithEncoding(loggingFile, Charsets.UTF_8));

            //
            // Write request
            //

            loggingWriter.println(new String(encoded, Charsets.US_ASCII));
        }
    }

    boolean validated = false;

    try {
        if (null == producer || null == owner) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid token.");
            return;
        }

        //
        // Build extra labels
        //

        Map<String, String> extraLabels = new HashMap<String, String>();
        //
        // Only set owner and potentially app, producer may vary
        //      
        extraLabels.put(Constants.OWNER_LABEL, owner);
        // FIXME(hbs): remove me
        if (null != application) {
            extraLabels.put(Constants.APPLICATION_LABEL, application);
            sensisionLabels.put(SensisionConstants.SENSISION_LABEL_APPLICATION, application);
        }

        boolean hasRange = false;

        long start = Long.MIN_VALUE;
        long end = Long.MAX_VALUE;

        if (null != startstr) {
            if (null == endstr) {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                        "Both " + Constants.HTTP_PARAM_START + " and " + Constants.HTTP_PARAM_END
                                + " should be defined.");
                return;
            }
            if (startstr.contains("T")) {
                start = fmt.parseDateTime(startstr).getMillis() * Constants.TIME_UNITS_PER_MS;
            } else {
                start = Long.valueOf(startstr);
            }
        }

        if (null != endstr) {
            if (null == startstr) {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                        "Both " + Constants.HTTP_PARAM_START + " and " + Constants.HTTP_PARAM_END
                                + " should be defined.");
                return;
            }
            if (endstr.contains("T")) {
                end = fmt.parseDateTime(endstr).getMillis() * Constants.TIME_UNITS_PER_MS;
            } else {
                end = Long.valueOf(endstr);
            }
        }

        if (Long.MIN_VALUE == start && Long.MAX_VALUE == end
                && null == request.getParameter(Constants.HTTP_PARAM_DELETEALL)) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Parameter "
                    + Constants.HTTP_PARAM_DELETEALL + " should be set when deleting a full range.");
            return;
        }

        if (Long.MIN_VALUE != start || Long.MAX_VALUE != end) {
            hasRange = true;
        }

        if (start > end) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                    "Invalid time range specification.");
            return;
        }

        //
        // Extract the class and labels selectors
        // The class selector and label selectors are supposed to have
        // values which use percent encoding, i.e. explicit percent encoding which
        // might have been re-encoded using percent encoding when passed as parameter
        //
        //

        Matcher m = EgressFetchHandler.SELECTOR_RE.matcher(selector);

        if (!m.matches()) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }

        String classSelector = URLDecoder.decode(m.group(1), "UTF-8");
        String labelsSelection = m.group(2);

        Map<String, String> labelsSelectors;

        try {
            labelsSelectors = GTSHelper.parseLabelsSelectors(labelsSelection);
        } catch (ParseException pe) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, pe.getMessage());
            return;
        }

        validated = true;

        //
        // Force 'producer'/'owner'/'app' from token
        //

        labelsSelectors.putAll(extraLabels);

        List<Metadata> metadatas = null;

        List<String> clsSels = new ArrayList<String>();
        List<Map<String, String>> lblsSels = new ArrayList<Map<String, String>>();
        clsSels.add(classSelector);
        lblsSels.add(labelsSelectors);

        metadatas = directoryClient.find(clsSels, lblsSels);

        response.setStatus(HttpServletResponse.SC_OK);
        response.setContentType("text/plain");

        PrintWriter pw = response.getWriter();
        StringBuilder sb = new StringBuilder();

        for (Metadata metadata : metadatas) {
            //
            // Remove from DB
            //

            if (!hasRange) {
                if (!dryrun) {
                    this.directoryClient.unregister(metadata);
                }
            }

            //
            // Remove data
            //

            long localCount = 0;

            if (!dryrun) {
                localCount = this.storeClient.delete(writeToken, metadata, start, end);
            }

            count += localCount;

            sb.setLength(0);
            GTSHelper.metadataToString(sb, metadata.getName(), metadata.getLabels());

            if (metadata.getAttributesSize() > 0) {
                GTSHelper.labelsToString(sb, metadata.getAttributes());
            } else {
                sb.append("{}");
            }

            pw.write(sb.toString());
            pw.write("\r\n");
            if (!metasSaturated) {
                if (gts < MAX_LOGGED_DELETED_GTS) {
                    metas.append(sb);
                    metas.append("\n");
                } else {
                    metasSaturated = true;
                    metas.append("...");
                    metas.append("\n");
                }
            }

            gts++;

            // Log detailed metrics for this GTS owner and app
            Map<String, String> labels = new HashMap<>();
            labels.put(SensisionConstants.SENSISION_LABEL_OWNER,
                    metadata.getLabels().get(Constants.OWNER_LABEL));
            labels.put(SensisionConstants.SENSISION_LABEL_APPLICATION,
                    metadata.getLabels().get(Constants.APPLICATION_LABEL));
            Sensision.update(
                    SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_DELETE_DATAPOINTS_PEROWNERAPP,
                    labels, localCount);
        }
    } catch (Exception e) {
        t = e;
        // If we have not yet written anything on the output stream, call sendError
        if (0 == gts) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
            return;
        } else {
            throw e;
        }
    } finally {
        if (null != loggingWriter) {
            Map<String, String> labels = new HashMap<String, String>();
            labels.put(SensisionConstants.SENSISION_LABEL_ID, new String(
                    OrderPreservingBase64.decode(dr.getId().getBytes(Charsets.US_ASCII)), Charsets.UTF_8));
            labels.put(SensisionConstants.SENSISION_LABEL_TYPE, dr.getType());
            Sensision.update(SensisionConstants.CLASS_WARP_DATALOG_REQUESTS_LOGGED, labels, 1);

            loggingWriter.close();
            if (validated) {
                loggingFile.renameTo(new File(loggingFile.getAbsolutePath() + DatalogForwarder.DATALOG_SUFFIX));
            } else {
                loggingFile.delete();
            }
        }

        Sensision.update(SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_DELETE_REQUESTS,
                sensisionLabels, 1);
        Sensision.update(SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_DELETE_GTS, sensisionLabels,
                gts);
        Sensision.update(SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_DELETE_DATAPOINTS,
                sensisionLabels, count);
        Sensision.update(SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_DELETE_TIME_US,
                sensisionLabels, (System.nanoTime() - nano) / 1000);

        LoggingEvent event = LogUtil.setLoggingEventAttribute(null, LogUtil.DELETION_TOKEN, token);
        event = LogUtil.setLoggingEventAttribute(event, LogUtil.DELETION_SELECTOR, selector);
        event = LogUtil.setLoggingEventAttribute(event, LogUtil.DELETION_START, startstr);
        event = LogUtil.setLoggingEventAttribute(event, LogUtil.DELETION_END, endstr);
        event = LogUtil.setLoggingEventAttribute(event, LogUtil.DELETION_METADATA, metas.toString());
        event = LogUtil.setLoggingEventAttribute(event, LogUtil.DELETION_COUNT, Long.toString(count));
        event = LogUtil.setLoggingEventAttribute(event, LogUtil.DELETION_GTS, Long.toString(gts));

        LogUtil.addHttpHeaders(event, request);

        if (null != t) {
            LogUtil.setLoggingEventStackTrace(null, LogUtil.STACK_TRACE, t);
        }

        LOG.info(LogUtil.serializeLoggingEvent(this.keyStore, event));
    }

    response.setStatus(HttpServletResponse.SC_OK);
}

From source file:io.warp10.standalone.StandaloneDirectoryClient.java

License:Apache License

public StandaloneDirectoryClient(DB db, final KeyStore keystore) {

    this.initNThreads = Integer.parseInt(WarpConfig.getProperties()
            .getProperty(Configuration.DIRECTORY_INIT_NTHREADS, DIRECTORY_INIT_NTHREADS_DEFAULT));

    this.db = db;
    this.keystore = keystore;

    this.aesKey = this.keystore.getKey(KeyStore.AES_LEVELDB_METADATA);
    this.classKey = this.keystore.getKey(KeyStore.SIPHASH_CLASS);
    this.classLongs = SipHashInline.getKey(this.classKey);

    this.labelsKey = this.keystore.getKey(KeyStore.SIPHASH_LABELS);
    this.labelsLongs = SipHashInline.getKey(this.labelsKey);

    //// ww  w  .  j  a  va 2s  . com
    // Read metadata from DB
    //

    if (null == db) {
        return;
    }

    DBIterator iter = db.iterator();

    iter.seek(METADATA_PREFIX);

    byte[] stop = "N".getBytes(Charsets.US_ASCII);

    long count = 0;

    Thread[] initThreads = new Thread[this.initNThreads];
    final AtomicBoolean[] stopMarkers = new AtomicBoolean[this.initNThreads];
    final LinkedBlockingQueue<Entry<byte[], byte[]>> resultQ = new LinkedBlockingQueue<Entry<byte[], byte[]>>(
            initThreads.length * 8192);

    for (int i = 0; i < initThreads.length; i++) {
        stopMarkers[i] = new AtomicBoolean(false);
        final AtomicBoolean stopMe = stopMarkers[i];
        initThreads[i] = new Thread(new Runnable() {
            @Override
            public void run() {

                byte[] bytes = new byte[16];

                AESWrapEngine engine = null;
                PKCS7Padding padding = null;

                if (null != keystore.getKey(KeyStore.AES_LEVELDB_METADATA)) {
                    engine = new AESWrapEngine();
                    CipherParameters params = new KeyParameter(keystore.getKey(KeyStore.AES_LEVELDB_METADATA));
                    engine.init(false, params);

                    padding = new PKCS7Padding();
                }

                TDeserializer deserializer = new TDeserializer(new TCompactProtocol.Factory());

                while (!stopMe.get()) {
                    try {

                        Entry<byte[], byte[]> result = resultQ.poll(100, TimeUnit.MILLISECONDS);

                        if (null == result) {
                            continue;
                        }

                        byte[] key = result.getKey();
                        byte[] value = result.getValue();

                        //
                        // Unwrap
                        //

                        byte[] unwrapped = null != engine ? engine.unwrap(value, 0, value.length) : value;

                        //
                        // Unpad
                        //

                        int padcount = null != padding ? padding.padCount(unwrapped) : 0;
                        byte[] unpadded = null != padding
                                ? Arrays.copyOf(unwrapped, unwrapped.length - padcount)
                                : unwrapped;

                        //
                        // Deserialize
                        //

                        Metadata metadata = new Metadata();
                        deserializer.deserialize(metadata, unpadded);

                        //
                        // Compute classId/labelsId and compare it to the values in the row key
                        //

                        // 128BITS
                        long classId = GTSHelper.classId(classLongs, metadata.getName());
                        long labelsId = GTSHelper.labelsId(labelsLongs, metadata.getLabels());

                        ByteBuffer bb = ByteBuffer.wrap(key).order(ByteOrder.BIG_ENDIAN);
                        bb.position(1);
                        long hbClassId = bb.getLong();
                        long hbLabelsId = bb.getLong();

                        // If classId/labelsId are incoherent, skip metadata
                        if (classId != hbClassId || labelsId != hbLabelsId) {
                            // FIXME(hbs): LOG
                            System.err.println("Incoherent class/labels Id for " + metadata);
                            continue;
                        }

                        // 128BITS
                        metadata.setClassId(classId);
                        metadata.setLabelsId(labelsId);

                        if (!metadata.isSetAttributes()) {
                            metadata.setAttributes(new HashMap<String, String>());
                        }

                        //
                        // Internalize Strings
                        //

                        GTSHelper.internalizeStrings(metadata);

                        synchronized (metadatas) {
                            if (!metadatas.containsKey(metadata.getName())) {
                                metadatas.put(metadata.getName(),
                                        (Map) new MapMaker().concurrencyLevel(64).makeMap());
                            }
                        }

                        synchronized (metadatas.get(metadata.getName())) {
                            if (!metadatas.get(metadata.getName()).containsKey(labelsId)) {
                                metadatas.get(metadata.getName()).put(labelsId, metadata);

                                //
                                // Store Metadata under 'id'
                                //
                                // 128BITS
                                GTSHelper.fillGTSIds(bytes, 0, classId, labelsId);
                                BigInteger id = new BigInteger(bytes);
                                metadatasById.put(id, metadata);

                                continue;
                            }
                        }

                        // FIXME(hbs): LOG
                        System.err.println("Duplicate labelsId for classId " + classId + ": " + metadata);
                        continue;

                    } catch (InvalidCipherTextException icte) {
                        throw new RuntimeException(icte);
                    } catch (TException te) {
                        throw new RuntimeException(te);
                    } catch (InterruptedException ie) {

                    }

                }
            }
        });

        initThreads[i].setDaemon(true);
        initThreads[i].setName("[Directory initializer #" + i + "]");
        initThreads[i].start();
    }

    try {

        long nano = System.nanoTime();

        while (iter.hasNext()) {
            Entry<byte[], byte[]> kv = iter.next();
            byte[] key = kv.getKey();
            if (Bytes.compareTo(key, stop) >= 0) {
                break;
            }

            boolean interrupted = true;

            while (interrupted) {
                interrupted = false;
                try {
                    resultQ.put(kv);
                    count++;
                    if (0 == count % 1000) {
                        Sensision.set(SensisionConstants.SENSISION_CLASS_CONTINUUM_DIRECTORY_GTS,
                                Sensision.EMPTY_LABELS, count);
                    }
                } catch (InterruptedException ie) {
                    interrupted = true;
                }
            }
        }

        //
        // Wait until resultQ is empty
        //

        while (!resultQ.isEmpty()) {
            try {
                Thread.sleep(100L);
            } catch (InterruptedException ie) {
            }
        }

        //
        // Notify the init threads to stop
        //

        for (int i = 0; i < initNThreads; i++) {
            stopMarkers[i].set(true);
        }

        nano = System.nanoTime() - nano;

        System.out.println("Loaded " + count + " GTS in " + (nano / 1000000.0D) + " ms");
    } finally {
        Sensision.set(SensisionConstants.SENSISION_CLASS_CONTINUUM_DIRECTORY_GTS, Sensision.EMPTY_LABELS,
                count);
        try {
            iter.close();
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        }
    }
}

From source file:io.warp10.standalone.StandaloneIngressHandler.java

License:Apache License

@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {

    String token = null;/*from w w w .j a v  a  2s.c o  m*/

    if (target.equals(Constants.API_ENDPOINT_UPDATE)) {
        baseRequest.setHandled(true);
    } else if (target.startsWith(Constants.API_ENDPOINT_UPDATE + "/")) {
        baseRequest.setHandled(true);
        token = target.substring(Constants.API_ENDPOINT_UPDATE.length() + 1);
    } else if (target.equals(Constants.API_ENDPOINT_META)) {
        handleMeta(target, baseRequest, request, response);
        return;
    } else {
        return;
    }

    try {
        //
        // CORS header
        //

        response.setHeader("Access-Control-Allow-Origin", "*");

        long nano = System.nanoTime();

        //
        // Extract DatalogRequest if specified
        //

        String datalogHeader = request.getHeader(Constants.getHeader(Configuration.HTTP_HEADER_DATALOG));

        DatalogRequest dr = null;

        boolean forwarded = false;

        if (null != datalogHeader) {
            byte[] bytes = OrderPreservingBase64.decode(datalogHeader.getBytes(Charsets.US_ASCII));

            if (null != datalogPSK) {
                bytes = CryptoUtils.unwrap(datalogPSK, bytes);
            }

            if (null == bytes) {
                throw new IOException("Invalid Datalog header.");
            }

            TDeserializer deser = new TDeserializer(new TCompactProtocol.Factory());

            try {
                dr = new DatalogRequest();
                deser.deserialize(dr, bytes);
            } catch (TException te) {
                throw new IOException();
            }

            token = dr.getToken();

            Map<String, String> labels = new HashMap<String, String>();
            labels.put(SensisionConstants.SENSISION_LABEL_ID, new String(
                    OrderPreservingBase64.decode(dr.getId().getBytes(Charsets.US_ASCII)), Charsets.UTF_8));
            labels.put(SensisionConstants.SENSISION_LABEL_TYPE, dr.getType());
            Sensision.update(SensisionConstants.CLASS_WARP_DATALOG_REQUESTS_RECEIVED, labels, 1);
            forwarded = true;
        }

        //
        // TODO(hbs): Extract producer/owner from token
        //

        if (null == token) {
            token = request.getHeader(Constants.getHeader(Configuration.HTTP_HEADER_TOKENX));
        }

        WriteToken writeToken;

        try {
            writeToken = Tokens.extractWriteToken(token);
        } catch (WarpScriptException ee) {
            throw new IOException(ee);
        }

        String application = writeToken.getAppName();
        String producer = Tokens.getUUID(writeToken.getProducerId());
        String owner = Tokens.getUUID(writeToken.getOwnerId());

        Map<String, String> sensisionLabels = new HashMap<String, String>();
        sensisionLabels.put(SensisionConstants.SENSISION_LABEL_PRODUCER, producer);

        long count = 0;
        long total = 0;

        File loggingFile = null;
        PrintWriter loggingWriter = null;

        try {
            if (null == producer || null == owner) {
                response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid token.");
                return;
            }

            //
            // Build extra labels
            //

            Map<String, String> extraLabels = new HashMap<String, String>();

            // Add labels from the WriteToken if they exist
            if (writeToken.getLabelsSize() > 0) {
                extraLabels.putAll(writeToken.getLabels());
            }

            // Force internal labels
            extraLabels.put(Constants.PRODUCER_LABEL, producer);
            extraLabels.put(Constants.OWNER_LABEL, owner);
            // FIXME(hbs): remove me, apps should be set in all tokens now...
            if (null != application) {
                extraLabels.put(Constants.APPLICATION_LABEL, application);
                sensisionLabels.put(SensisionConstants.SENSISION_LABEL_APPLICATION, application);
            } else {
                // remove application label
                extraLabels.remove(Constants.APPLICATION_LABEL);
            }

            //
            // Determine if content if gzipped
            //

            boolean gzipped = false;

            if (null != request.getHeader("Content-Type")
                    && "application/gzip".equals(request.getHeader("Content-Type"))) {
                gzipped = true;
            }

            BufferedReader br = null;

            if (gzipped) {
                GZIPInputStream is = new GZIPInputStream(request.getInputStream());
                br = new BufferedReader(new InputStreamReader(is));
            } else {
                br = request.getReader();
            }

            //
            // Get the present time
            //

            Long now = TimeSource.getTime();

            //
            // Check the value of the 'now' header
            //
            // The following values are supported:
            //
            // A number, which will be interpreted as an absolute time reference,
            // i.e. a number of time units since the Epoch.
            //
            // A number prefixed by '+' or '-' which will be interpreted as a
            // delta from the present time.
            //
            // A '*' which will mean to not set 'now', and to recompute its value
            // each time it's needed.
            //

            String nowstr = null != dr ? dr.getNow()
                    : request.getHeader(Constants.getHeader(Configuration.HTTP_HEADER_NOW_HEADERX));

            if (null != nowstr) {
                if ("*".equals(nowstr)) {
                    now = null;
                } else if (nowstr.startsWith("+")) {
                    try {
                        long delta = Long.parseLong(nowstr.substring(1));
                        now = now + delta;
                    } catch (Exception e) {
                        throw new IOException("Invalid base timestamp.");
                    }
                } else if (nowstr.startsWith("-")) {
                    try {
                        long delta = Long.parseLong(nowstr.substring(1));
                        now = now - delta;
                    } catch (Exception e) {
                        throw new IOException("Invalid base timestamp.");
                    }
                } else {
                    try {
                        now = Long.parseLong(nowstr);
                    } catch (Exception e) {
                        throw new IOException("Invalid base timestamp.");
                    }
                }
            }

            //
            // Open the logging file if logging is enabled
            //

            if (null != loggingDir) {
                long nanos = null != dr ? dr.getTimestamp() : TimeSource.getNanoTime();
                StringBuilder sb = new StringBuilder();
                sb.append(Long.toHexString(nanos));
                sb.insert(0, "0000000000000000", 0, 16 - sb.length());
                sb.append("-");
                if (null != dr) {
                    sb.append(dr.getId());
                } else {
                    sb.append(datalogId);
                }

                sb.append("-");
                sb.append(dtf.print(nanos / 1000000L));
                sb.append(Long.toString(1000000L + (nanos % 1000000L)).substring(1));
                sb.append("Z");

                if (null == dr) {
                    dr = new DatalogRequest();
                    dr.setTimestamp(nanos);
                    dr.setType(Constants.DATALOG_UPDATE);
                    dr.setId(datalogId);
                    dr.setToken(token);

                    if (null == now) {
                        //
                        // We MUST force 'now', otherwise forwarded metrics will not have a
                        // coherent time. This alters the semantics slightly but make it
                        // coherent across the board.
                        //
                        now = TimeSource.getTime();
                    }
                    dr.setNow(Long.toString(now));
                }

                if (null != dr && (!forwarded || (forwarded && this.logforwarded))) {

                    //
                    // Serialize the request
                    //

                    TSerializer ser = new TSerializer(new TCompactProtocol.Factory());

                    byte[] encoded;

                    try {
                        encoded = ser.serialize(dr);
                    } catch (TException te) {
                        throw new IOException(te);
                    }

                    if (null != this.datalogPSK) {
                        encoded = CryptoUtils.wrap(this.datalogPSK, encoded);
                    }

                    encoded = OrderPreservingBase64.encode(encoded);

                    loggingFile = new File(loggingDir, sb.toString());

                    loggingWriter = new PrintWriter(new FileWriterWithEncoding(loggingFile, Charsets.UTF_8));

                    //
                    // Write request
                    //

                    loggingWriter.println(new String(encoded, Charsets.US_ASCII));
                }

                //
                // Force 'now'
                //

                now = Long.parseLong(dr.getNow());
            }

            //
            // Loop on all lines
            //

            GTSEncoder lastencoder = null;
            GTSEncoder encoder = null;

            //
            // Chunk index when archiving
            //

            do {

                String line = br.readLine();

                if (null == line) {
                    break;
                }

                line = line.trim();

                if (0 == line.length()) {
                    continue;
                }

                //
                // Ignore comments
                //

                if ('#' == line.charAt(0)) {
                    continue;
                }

                //
                // Check for pushback
                // TODO(hbs): implement the actual push back if we are over the subscribed limit
                //

                if (count % PUSHBACK_CHECK_INTERVAL == 0) {
                    Sensision.update(
                            SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_UPDATE_DATAPOINTS_RAW,
                            sensisionLabels, count);
                    total += count;
                    count = 0;
                }

                count++;

                try {
                    encoder = GTSHelper.parse(lastencoder, line, extraLabels, now, maxValueSize, false);
                    //nano2 += System.nanoTime() - nano0;
                } catch (ParseException pe) {
                    Sensision.update(SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_UPDATE_PARSEERRORS,
                            sensisionLabels, 1);
                    throw new IOException("Parse error at '" + line + "'", pe);
                }

                if (encoder != lastencoder || lastencoder.size() > ENCODER_SIZE_THRESHOLD) {

                    //
                    // Check throttling
                    //

                    if (null != lastencoder) {

                        // 128BITS
                        lastencoder.setClassId(GTSHelper.classId(classKeyLongs, lastencoder.getName()));
                        lastencoder.setLabelsId(
                                GTSHelper.labelsId(labelsKeyLongs, lastencoder.getMetadata().getLabels()));

                        ThrottlingManager.checkMADS(lastencoder.getMetadata(), producer, owner, application,
                                lastencoder.getClassId(), lastencoder.getLabelsId());
                        ThrottlingManager.checkDDP(lastencoder.getMetadata(), producer, owner, application,
                                (int) lastencoder.getCount());
                    }

                    //
                    // Build metadata object to push
                    //

                    if (encoder != lastencoder) {
                        Metadata metadata = new Metadata(encoder.getMetadata());
                        metadata.setSource(Configuration.INGRESS_METADATA_SOURCE);
                        //nano6 += System.nanoTime() - nano0;
                        this.directoryClient.register(metadata);
                        //nano5 += System.nanoTime() - nano0;
                    }

                    if (null != lastencoder) {
                        this.storeClient.store(lastencoder);
                    }

                    if (encoder != lastencoder) {
                        lastencoder = encoder;
                    } else {
                        //lastencoder = null
                        //
                        // Allocate a new GTSEncoder and reuse Metadata so we can
                        // correctly handle a continuation line if this is what occurs next
                        //
                        Metadata metadata = lastencoder.getMetadata();
                        lastencoder = new GTSEncoder(0L);
                        lastencoder.setMetadata(metadata);
                    }
                }

                //
                // Write the line last, so we do not write lines which triggered exceptions
                //

                if (null != loggingWriter) {
                    loggingWriter.println(line);
                }
            } while (true);

            br.close();

            if (null != lastencoder && lastencoder.size() > 0) {
                // 128BITS
                lastencoder.setClassId(GTSHelper.classId(classKeyLongs, lastencoder.getName()));
                lastencoder
                        .setLabelsId(GTSHelper.labelsId(labelsKeyLongs, lastencoder.getMetadata().getLabels()));

                ThrottlingManager.checkMADS(lastencoder.getMetadata(), producer, owner, application,
                        lastencoder.getClassId(), lastencoder.getLabelsId());
                ThrottlingManager.checkDDP(lastencoder.getMetadata(), producer, owner, application,
                        (int) lastencoder.getCount());
                this.storeClient.store(lastencoder);
            }

            //
            // TODO(hbs): should we update the count in Sensision periodically so you can't trick the throttling mechanism?
            //
        } catch (WarpException we) {
            throw new IOException(we);
        } finally {
            this.storeClient.store(null);
            this.directoryClient.register(null);
            Sensision.update(SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_UPDATE_DATAPOINTS_RAW,
                    sensisionLabels, count);
            Sensision.update(SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_UPDATE_REQUESTS,
                    sensisionLabels, 1);
            Sensision.update(SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_UPDATE_TIME_US,
                    sensisionLabels, (System.nanoTime() - nano) / 1000);

            if (null != loggingWriter) {
                Map<String, String> labels = new HashMap<String, String>();
                labels.put(SensisionConstants.SENSISION_LABEL_ID, new String(
                        OrderPreservingBase64.decode(dr.getId().getBytes(Charsets.US_ASCII)), Charsets.UTF_8));
                labels.put(SensisionConstants.SENSISION_LABEL_TYPE, dr.getType());
                Sensision.update(SensisionConstants.CLASS_WARP_DATALOG_REQUESTS_LOGGED, labels, 1);

                loggingWriter.close();
                loggingFile.renameTo(new File(loggingFile.getAbsolutePath() + DatalogForwarder.DATALOG_SUFFIX));
            }

            //
            // Update stats with CDN
            //

            String cdn = request.getHeader(Constants.OVH_CDN_GEO_HEADER);

            if (null != cdn) {
                sensisionLabels.put(SensisionConstants.SENSISION_LABEL_CDN, cdn);
                // Per CDN stat is updated at the end, so update with 'total' + 'count'
                Sensision.update(SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_UPDATE_DATAPOINTS_RAW,
                        sensisionLabels, count + total);
                Sensision.update(SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_UPDATE_REQUESTS,
                        sensisionLabels, 1);
                Sensision.update(SensisionConstants.SENSISION_CLASS_CONTINUUM_STANDALONE_UPDATE_TIME_US,
                        sensisionLabels, (System.nanoTime() - nano) / 1000);
            }
        }

        response.setStatus(HttpServletResponse.SC_OK);
    } catch (Exception e) {
        if (!response.isCommitted()) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
            return;
        }
    }
}