Skip to content

Commit

Permalink
Merge pull request #48 from openepcis/GEN-53-add_custom_offset_to_eve…
Browse files Browse the repository at this point in the history
…ntTime

Gen 53 add custom offset to event time
  • Loading branch information
sboeckelmann authored Jun 20, 2024
2 parents 5af9ac7 + cc87177 commit 92b2191
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 284 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,26 @@
*/
package io.openepcis.testdata.generator.format;

import static com.fasterxml.jackson.annotation.JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.openepcis.testdata.generator.constants.TestDataGeneratorException;
import io.openepcis.testdata.generator.identifier.util.RandomSerialNumberGenerator;
import io.quarkus.runtime.annotations.RegisterForReflection;
import java.io.Serializable;
import java.time.OffsetDateTime;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
import org.eclipse.microprofile.openapi.annotations.media.Schema;

import java.io.Serializable;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;

import static com.fasterxml.jackson.annotation.JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE;

@Data
@NoArgsConstructor
Expand All @@ -46,23 +54,47 @@ public class EventTime implements Serializable {
@NotNull(message = "Timezone offset cannot be Null")
private String timeZoneOffset;

private RandomDateTimeGenerator randomDateTimeGenerator;
@Schema(type = SchemaType.INTEGER, description = "Custom offset From value for generating eventTime based on parent eventTime")
private Integer customOffsetFrom;

@Schema(type = SchemaType.INTEGER, description = "Custom offset To value for generating eventTime based on parent eventTime")
private Integer customOffsetTo;

public OffsetDateTime generate() {
@Schema(type = SchemaType.STRING, description = "Custom offset type value for generating eventTime based on parent eventTime ex: seconds/minutes/hours/days")
private String customOffsetType;

public OffsetDateTime generate(final OffsetDateTime parentEventTime, final RandomSerialNumberGenerator randomDateTimeGenerator) {
try {
if (specificTime != null) {
//For specific time return provided date time
return specificTime;
} else if (fromTime != null && toTime != null) {
//For range get the random date between from and to value using the Mersenne Twister
return Instant.ofEpochMilli(randomDateTimeGenerator.generateIntInRange(fromTime.toInstant().toEpochMilli(), toTime.toInstant().toEpochMilli())).atZone(ZoneId.systemDefault()).toOffsetDateTime();
} else if (parentEventTime != null && customOffsetFrom != null && customOffsetTo != null && StringUtils.isNotBlank(customOffsetType)) {
//For custom offset from and to date time get the value based on the parentEventTime if parentEventTime is not null
return calculateCustomOffset(parentEventTime, randomDateTimeGenerator);
}

if (randomDateTimeGenerator == null) {
randomDateTimeGenerator = new RandomDateTimeGenerator(fromTime, toTime);
}

return randomDateTimeGenerator.nextDate();
//For any other non-matching case return the current date time
return Instant.ofEpochMilli(System.currentTimeMillis()).atZone(ZoneId.systemDefault()).toOffsetDateTime();
} catch (Exception ex) {
throw new TestDataGeneratorException(
"Exception occurred during creation of assignment of the Event Time, Please check the values provided values for EventTime : "
+ ex.getMessage(), ex);
throw new TestDataGeneratorException("Exception occurred during creation of assignment of the Event Time : " + ex.getMessage(), ex);
}
}

//Method to calculate the eventTime based on custom offset values
private OffsetDateTime calculateCustomOffset(final OffsetDateTime parentEventTime, final RandomSerialNumberGenerator randomDateTimeGenerator) {
//Using from and to value generate a random number using Mersenne twister
final long offsetValue = randomDateTimeGenerator.generateIntInRange(customOffsetFrom, customOffsetTo);

//Append the Minutes/Hours/Days to the parent event eventTime based on the custom offset type value
return switch (customOffsetType.toLowerCase()) {
case "seconds" -> parentEventTime.plus(offsetValue, ChronoUnit.SECONDS);
case "minutes" -> parentEventTime.plus(offsetValue, ChronoUnit.MINUTES);
case "hours" -> parentEventTime.plus(offsetValue, ChronoUnit.HOURS);
case "days" -> parentEventTime.plus(offsetValue, ChronoUnit.DAYS);
default -> throw new IllegalArgumentException("Unsupported customOffsetType for eventTime generation : " + customOffsetType);
};
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import io.openepcis.testdata.generator.constants.RandomizationType;
import io.openepcis.testdata.generator.constants.TestDataGeneratorException;
import lombok.Getter;
import org.apache.commons.math3.random.MersenneTwister;
import org.apache.commons.math3.random.RandomGenerator;

Expand All @@ -27,6 +28,7 @@
* Class to generate the random numbers using the Mersenne Twister (MT) algorithm where if the seed is provided then Random numbers are generated based on the seed. If no seed is provided then truly random numbers are generated.
*/
public class RandomSerialNumberGenerator {
@Getter
private final RandomGenerator random;

// Public method to get the singleton instance
Expand Down Expand Up @@ -158,4 +160,18 @@ private String generateRandomID(final String characterSet, final int minLength,

return randomID.toString();
}

/**
* Method to generate random number based on provided lower and upper bound using the Mersenne twister
*
* @param lowerBound lower bound for the long number to be generated
* @param upperBound upper bound for the long number to be generated
* @return returns the random number between lower and upper bound
*/
public long generateIntInRange(final long lowerBound, final long upperBound) {
final long lower = Math.min(lowerBound, upperBound);
final long upper = Math.max(lowerBound, upperBound);
final long range = upper - lower + 1;
return (long) (random.nextDouble() * range) + lower;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ public EPCISEventDownstreamHandler toEPCISDownstreamHandler() {
return epcisEventDownstreamHandler;
}

protected void configure(final E epcisEvent) {
protected void configure(final E epcisEvent, final List<EventIdentifierTracker> parentTracker) {

final IdentifierVocabularyType syntax = typeInfo.getLocationPartyIdentifierSyntax();
try {

// Call the method to add the When dimension information associated with the event
configureWhenDimension(epcisEvent);
configureWhenDimension(epcisEvent, parentTracker);

// Call the method to add the Where dimension information associated with the event
configureWhereDimension(epcisEvent, syntax);
Expand Down Expand Up @@ -133,12 +133,13 @@ protected void configure(final E epcisEvent) {

// Private method used to add the When dimension (Event time, Event Timezone offset, Record time)
// related information during the creation of event
private void configureWhenDimension(final E epcisEvent) {
private void configureWhenDimension(final E epcisEvent, final List<EventIdentifierTracker> parentTracker) {
// Set TimeZone Offset
epcisEvent.setEventTimeZoneOffset(typeInfo.getEventTime().getTimeZoneOffset());

// Setting the event Time
epcisEvent.setEventTime(typeInfo.getEventTime().generate());
// Setting the event Time, if custom option selected then set eventTime based on parent eventTime
final OffsetDateTime parentEventTime = CollectionUtils.isNotEmpty(parentTracker) ? parentTracker.get(0).getEvent().getEventTime() : null;
epcisEvent.setEventTime(typeInfo.getEventTime().generate(parentEventTime, randomSerialNumberGenerator));

// Set Record Time
if (typeInfo.getRecordTimeType() == RecordTimeType.SAME_AS_EVENT_TIME) {
Expand Down Expand Up @@ -211,7 +212,7 @@ private void configureErrorInformation(
var err = new ErrorDeclaration();

// Set the Error declaration time
err.setDeclarationTime(typeInfo.getErrorDeclaration().getDeclarationTime().generate());
err.setDeclarationTime(typeInfo.getErrorDeclaration().getDeclarationTime().generate(null, randomSerialNumberGenerator));

// Set the Error declaration time offset this is missing in openEpcis-parent
// err.setDeclarationTimezoneOffset(typeInfo.getErrorDeclaration().getDeclarationTime().getTimeZoneOffset());
Expand Down Expand Up @@ -279,12 +280,12 @@ public List<String> referencedParentIdentifier(final List<EventIdentifierTracker
//Common method to built or import the parentID for Aggregation/Transaction/Association eventTypes
public void configureParent(final EPCISEvent event, final List<EventIdentifierTracker> parentTracker, final Identifier matchingParentId) {
// Determine the event type and cast it accordingly
if (event instanceof AggregationEvent) {
((AggregationEvent) event).setParentID(buildParentID(matchingParentId, parentTracker));
} else if (event instanceof TransactionEvent) {
((TransactionEvent) event).setParentID(buildParentID(matchingParentId, parentTracker));
} else if (event instanceof AssociationEvent) {
((AssociationEvent) event).setParentID(buildParentID(matchingParentId, parentTracker));
if (event instanceof AggregationEvent aggEvent) {
aggEvent.setParentID(buildParentID(matchingParentId, parentTracker));
} else if (event instanceof TransactionEvent txnEvent) {
txnEvent.setParentID(buildParentID(matchingParentId, parentTracker));
} else if (event instanceof AssociationEvent assocEvent) {
assocEvent.setParentID(buildParentID(matchingParentId, parentTracker));
}
}

Expand Down Expand Up @@ -366,7 +367,7 @@ public List<String> referencedEpcsIdentifierGenerator(
}

//Add the identifiers from ParentID Count only if the inheriting event is ObjectEvent or TransformationEvent
if (epc.getParentNodeId() != 0 && epc.getInheritParentCount() > 0 && inheritParentIdCountFlag) {
if (epc.getParentNodeId() != 0 && epc.getInheritParentCount() > 0 && Boolean.TRUE.equals(inheritParentIdCountFlag)) {
// When user wants to inherit Parent-Ids from parent node into child node get the matching
// Parent Identifiers. (AggregationEvent -> ObjectEvent)
parentTracker.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public AggregationEventCreationModel(
@Override
public AggregationEvent create(final List<EventIdentifierTracker> parentTracker) {
var epcisEvent = new AggregationEvent();
super.configure(epcisEvent); //Add common info of AggregationEvent
super.configure(epcisEvent, parentTracker); //Add common info of AggregationEvent
super.configureParent(epcisEvent, parentTracker, matchingParentId); //Add parentID of AggregationEvent

configureCommons(epcisEvent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public AssociationEventCreationModel(
@Override
public AssociationEvent create(final List<EventIdentifierTracker> parentTracker) {
var epcisEvent = new AssociationEvent();
super.configure(epcisEvent); //Add common info of AssociationEvent
super.configure(epcisEvent, parentTracker); //Add common info of AssociationEvent
super.configureParent(epcisEvent, parentTracker, matchingParentId); //Add parentID of AssociationEvent

configureCommons(epcisEvent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public ObjectEventCreationModel(
@Override
public ObjectEvent create(final List<EventIdentifierTracker> parentTracker) {
var epcisEvent = new ObjectEvent();
super.configure(epcisEvent);
super.configure(epcisEvent, parentTracker);
configureCommons(epcisEvent);
configureIdentifiers(epcisEvent, parentTracker);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public TransactionEventCreationModel(
@Override
public TransactionEvent create(final List<EventIdentifierTracker> parentTracker) {
var epcisEvent = new TransactionEvent();
super.configure(epcisEvent); //Add common info of TransactionEvent
super.configure(epcisEvent, parentTracker); //Add common info of TransactionEvent
super.configureParent(epcisEvent, parentTracker, matchingParentId); //Add parentID of TransactionEvent

configureCommons(epcisEvent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public TransformationEventCreationModel(
@Override
public TransformationEvent create(final List<EventIdentifierTracker> parentTracker) {
var epcisEvent = new TransformationEvent();
super.configure(epcisEvent);
super.configure(epcisEvent, parentTracker);
configureCommons(epcisEvent);
configureInputIdentifiers(epcisEvent, parentTracker);
configureOutputEpcs(epcisEvent);
Expand Down
Loading

0 comments on commit 92b2191

Please sign in to comment.