/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.jmeter.report.processor;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.jmeter.report.core.Sample;
import org.apache.jmeter.report.core.SampleException;
import org.apache.jmeter.report.core.SampleMetadata;
import org.apache.jmeter.samplers.SampleSaveConfiguration;
import org.apache.jmeter.save.CSVSaveService;
import org.apache.jmeter.util.JMeterUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Consume samples using the JMeter timestamp property (defaulting to {@link SampleSaveConfiguration#MILLISECONDS}) and reproduce them as a long
* value (for faster treatment later in the consuming chain).
*
* @since 3.0
*/
public class NormalizerSampleConsumer extends AbstractSampleConsumer {
private static final Logger log = LoggerFactory.getLogger(NormalizerSampleConsumer.class);
private static final String TIMESTAMP_FORMAT =
JMeterUtils.getPropDefault(
"jmeter.save.saveservice.timestamp_format", // $NON-NLS-1$
SampleSaveConfiguration.MILLISECONDS);
private static final String PARSE_TIMESTAMP_EXCEPTION_MESSAGE =
"Could not parse timeStamp <%s> using format defined by property jmeter.save.saveservice.timestamp_format=%s on sample %s ";
/**
* index of the timeStamp column
*/
private int timestamp;
/**
* is format ms
*/
private boolean isMillisFormat;
/**
* null if format is isMillisFormat is true
*/
private final SimpleDateFormat dateFormat = createFormatter();
private SampleMetadata sampleMetadata;
@Override
public void startConsuming() {
sampleMetadata = getConsumedMetadata(0);
timestamp = sampleMetadata.ensureIndexOf(CSVSaveService.TIME_STAMP);
super.setProducedMetadata(sampleMetadata, 0);
startProducing();
}
/**
* @return null if format is ms or a SimpleDateFormat
* @throws SampleException is format is none
*/
private SimpleDateFormat createFormatter() {
if(SampleSaveConfiguration.NONE.equalsIgnoreCase(TIMESTAMP_FORMAT)) {
throw new SampleException("'none' format for 'jmeter.save.saveservice.timestamp_format' property is not accepted for report generation");
}
log.info("Using format, '{}', to parse timeStamp field", TIMESTAMP_FORMAT);
isMillisFormat = SampleSaveConfiguration.MILLISECONDS.equalsIgnoreCase(TIMESTAMP_FORMAT);
SimpleDateFormat formatter = null;
// Prepare for a pretty date
if (!isMillisFormat) {
formatter = new SimpleDateFormat(TIMESTAMP_FORMAT);
}
return formatter;
}
@Override
public void consume(Sample s, int channel) {
Date date = null;
try {
String tStr = s.getData(timestamp);
if(isMillisFormat) {
date = new Date(Long.parseLong(tStr));
} else {
date = dateFormat.parse(tStr);
}
} catch (Exception e) {
throw new SampleException(String.format(
PARSE_TIMESTAMP_EXCEPTION_MESSAGE, s.getData(timestamp),
TIMESTAMP_FORMAT, s.toString()), e);
}
long time = date.getTime();
int cc = sampleMetadata.getColumnCount();
String[] data = new String[cc];
for (int i = 0; i < cc; i++) {
if (i == timestamp) {
data[i] = Long.toString(time);
} else {
data[i] = s.getData(i);
}
}
Sample rewritten = new Sample(s.getSampleRow(), sampleMetadata, data);
super.produce(rewritten, 0);
}
@Override
public void stopConsuming() {
super.stopProducing();
}
}