Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import eu.arrowhead.common.CommonConstants;
import eu.arrowhead.common.Defaults;
Expand Down Expand Up @@ -514,6 +515,9 @@ private void handleSessionStepSuccess(final ChoreographerExecutedStepResultDTO p
} else {
final List<ChoreographerStep> executableSteps = new ArrayList<>();
boolean executable = true;

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete these stuffs:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan("eu.arrowhead.core.choreographer.servic");

StepResponseEvaluation evaluator =  new StepResponseEvaluation(); 	//context.getBean(StepResponseEvaluation.class);	
// new StepResponseEvaluation();
'''

context.scan("eu.arrowhead.core.choreographer.servic");

for (final ChoreographerStep nextStep : nextSteps) {
// next step is only executable if all of its previous steps are done
Expand All @@ -539,7 +543,7 @@ private void handleSessionStepSuccess(final ChoreographerExecutedStepResultDTO p

} else if (ChoreographerSessionStepStartCondition.TRUE == nextStep.getStartCondition()) {
executable = false;
StepResponseEvaluation evaluator = new StepResponseEvaluation();
StepResponseEvaluation evaluator = context.getBean(StepResponseEvaluation.class);

for (final ChoreographerSessionStep sessionStep : previousSessionSteps) {
if (ChoreographerSessionStepStatus.DONE == sessionStep.getStatus()
Expand All @@ -552,7 +556,7 @@ private void handleSessionStepSuccess(final ChoreographerExecutedStepResultDTO p

} else if (ChoreographerSessionStepStartCondition.FALSE == nextStep.getStartCondition()) {
executable = false;
StepResponseEvaluation evaluator = new StepResponseEvaluation();
StepResponseEvaluation evaluator = context.getBean(StepResponseEvaluation.class);

for (final ChoreographerSessionStep sessionStep : previousSessionSteps) {
if (ChoreographerSessionStepStatus.DONE == sessionStep.getStatus()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,48 @@
import com.fasterxml.jackson.databind.JsonNode;
import java.lang.String;

import org.springframework.stereotype.Service;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@Service
class StepResponseEvaluation {

private final Logger logger = LogManager.getLogger(StepResponseEvaluation.class);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add:

@Autowired
private ObjectMapper mapper;

public Boolean stepOutputValue(String message, String path, String threshold) {
// if sth used is null throw exception
if (path == null || message == null || threshold == null) {
throw new IllegalArgumentException("The argument cannot be null");
}

// extract value from message given in path
String value = getJsonValue(path, message);
if(value == null)
throw new IllegalArgumentException("Unable to restore value from path");

// extract value from threshold
// convert the extracted value to wrapper type
// compare and return
String[] thresholdPair = threshold.split(":");
if(thresholdPair.length != 2)
throw new IllegalArgumentException("The threshold valuable must have two component, seperated by a \":\" character.");

if (thresholdPair[0].equals("integer")) {
Integer limit = Integer.parseInt(thresholdPair[1]);
return Integer.parseInt(value) >= limit;
} else if (thresholdPair[0].equals("long")) {
Long limit = Long.parseLong(thresholdPair[1]);
return Long.parseLong(value) >= limit;
} else if (thresholdPair[0].equals("boolean")) {
return thresholdPair[1].equals(value);
} else if (thresholdPair[0].equals("string")) {
return thresholdPair[1].equals(value);
} else {
throw new IllegalArgumentException(
"Invalid threshold type. The threshold type can only be long, integer, boolean or string.");
}
}

private String getJsonValue(String path, String message) {
ObjectMapper objectMapper = new ObjectMapper();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should @Autowire the object mapper and not instatatiate it every time when the method is called.

Expand All @@ -36,7 +77,9 @@ private String getJsonValue(String path, String message) {
for (int i = 0; i < keys.length - 1; i += 2) {
if (keys[i].equals("array")) {
jsonNode = jsonNode.get(keys[i + 1]);
jsonNode = jsonNode.get(Integer.parseInt(keys[i + 2]));
if(jsonNode.size() <= Integer.parseInt(keys[i + 1]))
throw new IndexOutOfBoundsException("The index of json array is out of range.");
jsonNode = jsonNode.get(Integer.parseInt(keys[i + 1]));
} else if (keys[i].equals("map")) {
jsonNode = jsonNode.get(keys[i + 1]);
} else if (keys[i].equals("value")) {
Expand All @@ -46,53 +89,12 @@ private String getJsonValue(String path, String message) {
}

} catch (IOException e) {
e.printStackTrace();
logger.error(e.getMessage());
logger.debug(e);
}

return value;

}

public Boolean stepOutputValue(String message, String path, String threshold) {
// if sth used is null throw exception
if (path == null || message == null || threshold == null) {
throw new IllegalArgumentException("The argument cannot be null");
}

// extract value from message given in path
String value = getJsonValue(path, message);

// extract value from threshold
// convert the extracted value to wrapper type
// compare and return
String[] thresholdPair = threshold.split(":");
if (thresholdPair[0].equals("Integer")) {
Integer limit = Integer.parseInt(thresholdPair[1]);
if (Integer.parseInt(value) >= limit)
return true;
else
return false;
} else if (thresholdPair[0].equals("Long")) {
Long limit = Long.parseLong(thresholdPair[1]);
if (Long.parseLong(value) >= limit)
return true;
else
return false;
} else if (thresholdPair[0].equals("Boolean")) {
Boolean limit;
if (thresholdPair[1].equals(value))
return true;
else
return false;
} else if (thresholdPair[0].equals("String")) {
String limit;
if (thresholdPair[1].equals(value))
return true;
else
return false;
} else {
throw new IllegalArgumentException(
"Invalid threshold type. The threshold type can only be Long, Integer, Boolean or String.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import eu.arrowhead.common.exception.InvalidParameterException;
import eu.arrowhead.core.choreographer.graph.StepGraph;
import eu.arrowhead.core.choreographer.graph.StepGraphUtils;
import eu.arrowhead.common.dto.internal.ChoreographerSessionStepStartCondition;

@Service
public class ChoreographerPlanValidator {
Expand Down Expand Up @@ -275,6 +276,9 @@ private ChoreographerStepRequestDTO validateStep(final ChoreographerStepRequestD
result.setStaticParameters(step.getStaticParameters());
result.setQuantity(step.getQuantity() != null ? step.getQuantity() : 1);
result.setServiceRequirement(handleServiceRequirement(step.getServiceRequirement(), origin));
result.setStartCondition(handleStartCondition(step.getStartCondition()));
result.setThreshold(handleThreshold(step.getThreshold()));
result.setPath(handlePath(step.getPath()));

if (step.getNextStepNames() != null) {
final List<String> resultNextStepNames = new ArrayList<String>(step.getNextStepNames().size());
Expand Down Expand Up @@ -354,7 +358,73 @@ private List<ChoreographerActionRequestDTO> validateAndNormalizeActions(final Li

return result;
}
//-------------------------------------------------------------------------------------------------
private String handleThreshold(final String threshold) {
logger.debug("handleThreshold started...");
if(threshold == null)
return null;

String elements[] = threshold.split(":");
String value;

if(elements.length != 2)
throw new IllegalArgumentException("The threshold valuable must have two component, seperated by a \":\" character.");
String type = elements[0].toLowerCase();
if( type.equals("long")) {
try{
value = ((Long) Long.parseLong(elements[1])).toString();
}
catch ( NumberFormatException e){
throw new IllegalArgumentException("The long value must be a long number.");
}
} else if( type.equals("int")) {
try{
value = ((Integer) Integer.parseInt(elements[1])).toString();
}
catch ( NumberFormatException e){
throw new IllegalArgumentException("The integer value must be an integer number.");
}
} else if( type.equals("boolean")) {
value = elements[1].toLowerCase();
if( value != "true" && value != "false")
throw new IllegalArgumentException("Invalid value. Boolean value must be either true or false.");
} else if( type.equals("string")) {
value = elements[1].toLowerCase();
} else {
throw new IllegalArgumentException("Invalid threshold type. The threshold type can only be long, integer, boolean or string.");
}

return type + ":" + value;
}

//-------------------------------------------------------------------------------------------------
private ChoreographerSessionStepStartCondition handleStartCondition(final ChoreographerSessionStepStartCondition startCondition) {
logger.debug("handleStartCondition started...");

return startCondition;
}
//-------------------------------------------------------------------------------------------------
private String handlePath(final String path) {
logger.debug("handlePath started...");
if(path== null)
return null;

String elements[] = path.split("/");
for (int i = 0; i < elements.length - 1; i += 2) {
if ( elements[i].equals("array")) {
try {
Integer.parseInt( elements[i + 1]);
} catch (Exception e) {
throw new IllegalArgumentException("The path of a json array must have an integer as index. ");
}
} else if ( !elements[i].equals("map") && !elements[i].equals("value")) {
throw new IllegalArgumentException("The type of path element must be \"array\", \"map\" or \"value\".");
}
}

return path;

}
//-------------------------------------------------------------------------------------------------
private ChoreographerActionRequestDTO validateAndNormalizeAction(final ChoreographerActionRequestDTO action) {
logger.debug("validateAndNormalizeAction started...");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import eu.arrowhead.common.database.entity.ChoreographerSessionStep;
import eu.arrowhead.common.database.entity.ChoreographerStep;
import eu.arrowhead.common.database.entity.ChoreographerStepNextStepConnection;
import eu.arrowhead.common.dto.internal.ChoreographerSessionStepStartCondition;
import eu.arrowhead.common.dto.internal.ChoreographerSessionStepStatus;
import eu.arrowhead.common.dto.internal.ChoreographerStartSessionDTO;
import eu.arrowhead.common.dto.shared.ChoreographerAbortStepRequestDTO;
Expand Down Expand Up @@ -1677,12 +1678,12 @@ public void testReceiveSessionStepDoneCannotStartNextStep() {
final ChoreographerAction action = new ChoreographerAction();
action.setId(11);
final ChoreographerStep nextStep = new ChoreographerStep();
nextStep.setStartCondition("AND");
nextStep.setStartCondition(ChoreographerSessionStepStartCondition.AND);
final ChoreographerStep otherPrevStep = new ChoreographerStep();
otherPrevStep.setStartCondition("AND");
otherPrevStep.setStartCondition(ChoreographerSessionStepStartCondition.AND);
final ChoreographerStep step = new ChoreographerStep();
step.setAction(action);
step.setStartCondition("AND");
step.setStartCondition(ChoreographerSessionStepStartCondition.AND);
step.setNextStepConnections(Set.of(new ChoreographerStepNextStepConnection(step, nextStep)));

nextStep.setPreviousStepConnections(Set.of(new ChoreographerStepNextStepConnection(step, nextStep),
Expand Down Expand Up @@ -1724,14 +1725,14 @@ public void testReceiveSessionStepDoneStartNextStep() { // executeStep is alread
action.setName("action");
action.setPlan(plan);
final ChoreographerStep nextStep = new ChoreographerStep();
nextStep.setStartCondition("AND");
nextStep.setStartCondition(ChoreographerSessionStepStartCondition.AND);
nextStep.setName("nextStep");
nextStep.setAction(action);
final ChoreographerStep otherPrevStep = new ChoreographerStep();
otherPrevStep.setStartCondition("AND");
otherPrevStep.setStartCondition(ChoreographerSessionStepStartCondition.AND);
final ChoreographerStep step = new ChoreographerStep();
step.setAction(action);
step.setStartCondition("AND");
step.setStartCondition(ChoreographerSessionStepStartCondition.AND);
step.setNextStepConnections(Set.of(new ChoreographerStepNextStepConnection(step, nextStep)));

nextStep.setPreviousStepConnections(Set.of(new ChoreographerStepNextStepConnection(step, nextStep),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;

import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
Expand Down Expand Up @@ -83,13 +85,14 @@ public class ChoreographerStep {
@Column (nullable = false, updatable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
private ZonedDateTime updatedAt;

@Column(columnDefinition = "TEXT")
private String startCondition;
@Column(nullable = false, length = CoreDefaults.VARCHAR_BASIC)
@Enumerated(EnumType.STRING)
private ChoreographerSessionStepStartCondition startCondition;

@Column(columnDefinition = "TEXT")
@Column(columnDefinition = "MEDIUMTEXT")
private String threshold;

@Column(columnDefinition = "TEXT")
@Column(columnDefinition = "MEDIUMTEXT")
private String path;

@OneToMany (mappedBy = "from", fetch = FetchType.EAGER, orphanRemoval = true)
Expand All @@ -116,7 +119,7 @@ public ChoreographerStep(final String name, final ChoreographerAction action, fi
this.srTemplate = srTemplate;
this.staticParameters = staticParameters;
this.quantity = quantity;
this.startCondition = "AND";
this.startCondition = ChoreographerSessionStepStartCondition.AND;
this.threshold = null;
this.path = null;
}
Expand All @@ -131,12 +134,13 @@ public ChoreographerStep(final String name, final ChoreographerAction action, fi
this.srTemplate = srTemplate;
this.staticParameters = staticParameters;
this.quantity = quantity;
switch(startCondition) {
case TRUE: this.startCondition = "TRUE"; break;
case FALSE: this.startCondition = "FALSE"; break;
case OR: this.startCondition = "OR"; break;
default: this.startCondition = "AND";
}
this.startCondition = startCondition;
// switch(startCondition) {
// case TRUE: this.startCondition = "TRUE"; break;
// case FALSE: this.startCondition = "FALSE"; break;
// case OR: this.startCondition = "OR"; break;
// default: this.startCondition = "AND";
// }
this.threshold = threshold;
this.path = path;
}
Expand All @@ -157,12 +161,13 @@ public ChoreographerStep(final String name, final ChoreographerAction action, fi
public Set<ChoreographerStepNextStepConnection> getNextStepConnections() { return nextStepConnections; }
public Set<ChoreographerStepNextStepConnection> getPreviousStepConnections() { return previousStepConnections; }
public ChoreographerSessionStepStartCondition getStartCondition() {
switch(startCondition) {
case "TRUE": return ChoreographerSessionStepStartCondition.TRUE;
case "FALSE": return ChoreographerSessionStepStartCondition.FALSE;
case "OR": return ChoreographerSessionStepStartCondition.OR;
default: return ChoreographerSessionStepStartCondition.AND;
}
return startCondition;
// switch(startCondition) {
// case "TRUE": return ChoreographerSessionStepStartCondition.TRUE;
// case "FALSE": return ChoreographerSessionStepStartCondition.FALSE;
// case "OR": return ChoreographerSessionStepStartCondition.OR;
// default: return ChoreographerSessionStepStartCondition.AND;
// }
}
public String getThreshold() {return this.threshold;}
public String getPath() {return this.path;}
Expand Down Expand Up @@ -192,7 +197,7 @@ public Set<ChoreographerStep> getPreviousSteps() {
public void setUpdatedAt(final ZonedDateTime updatedAt) { this.updatedAt = updatedAt; }
public void setNextStepConnections(final Set<ChoreographerStepNextStepConnection> nextStepConnections) { this.nextStepConnections = nextStepConnections; }
public void setPreviousStepConnections(final Set<ChoreographerStepNextStepConnection> previousStepConnections) { this.previousStepConnections = previousStepConnections; }
public void setStartCondition(final String startCondition) {this.startCondition = startCondition;}
public void setStartCondition(final ChoreographerSessionStepStartCondition startCondition) {this.startCondition = startCondition;}
public void setThreshold(final String threshold) { this.threshold = threshold;}
public void setPath(final String path) { this.path = path;}

Expand Down
3 changes: 3 additions & 0 deletions scripts/create_arrowhead_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,9 @@ CREATE TABLE IF NOT EXISTS `choreographer_step` (
`quantity` int(20) NOT NULL DEFAULT 1,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`startCondition` varchar(15) NOT NULL DEFAULT 'AND',
`threshold` mediumtext,
`path` mediumtext,
PRIMARY KEY (`id`),
UNIQUE KEY `name_action_id_unique_key` (`name`, `action_id`),
CONSTRAINT `action` FOREIGN KEY (`action_id`) REFERENCES `choreographer_action` (`id`) ON DELETE CASCADE
Expand Down