Commit 5db4beea authored by Jan Marchel's avatar Jan Marchel
Browse files

edge support

parent 01d02830
Pipeline #20892 failed with stages
in 1 minute and 34 seconds
......@@ -188,7 +188,7 @@
<dependency>
<groupId>cloud.morphemic.connectors</groupId>
<artifactId>proactive_client</artifactId>
<version>2.0-SNAPSHOT</version>
<version>2.5-20220421.141237-9</version>
</dependency>
<dependency>
<groupId>io.github.cloudiator.client</groupId>
......
......@@ -2,6 +2,7 @@ package eu.melodic.upperware.adapter.communication.proactive;
import cloud.morphemic.connectors.proactive.IProactiveClientServiceConnector;
import org.activeeon.morphemic.model.ByonNode;
import org.activeeon.morphemic.model.EdgeNode;
import org.activeeon.morphemic.model.SubmittedJobType;
import org.apache.commons.lang3.tuple.Pair;
import org.json.JSONArray;
......@@ -24,4 +25,7 @@ public interface ProactiveClientServiceForAdapter extends IProactiveClientServic
int addByonNodes(Map<String, String> byonIdPerComponent, String jobId);
void waitForJobFinish(String jobId, SubmittedJobType expectedJobType);
List<ByonNode> getByonNodeList(String jobId);
List<EdgeNode> getEdgeNodeList(String jobId);
int addEdgeNodes(Map<String, String> edgeIdPerComponent, String jobId);
}
......@@ -4,6 +4,7 @@ import cloud.morphemic.connectors.proactive.ProactiveClientServiceConnector;
import eu.melodic.upperware.adapter.exception.AdapterException;
import lombok.extern.slf4j.Slf4j;
import org.activeeon.morphemic.model.ByonNode;
import org.activeeon.morphemic.model.EdgeNode;
import org.activeeon.morphemic.model.SubmittedJobType;
import org.apache.commons.lang3.tuple.Pair;
import org.json.JSONArray;
......@@ -150,4 +151,14 @@ public class ProactiveClientServiceForAdapterImpl extends ProactiveClientService
return getPAGateway().map(paGateway -> paGateway.getByonNodeList(jobId)).orElse(Collections.emptyList());
}
@Override
public List<EdgeNode> getEdgeNodeList(String jobId) {
return getPAGateway().map(paGateway -> paGateway.getEdgeNodeList(jobId)).orElse(Collections.emptyList());
}
@Override
public int addEdgeNodes(Map<String, String> edgeIdPerComponent, String jobId) {
return getPAGateway().map(paGateway -> paGateway.addEdgeNodes(edgeIdPerComponent, jobId)).orElse(-1);
}
}
......@@ -6,8 +6,6 @@ import eu.melodic.upperware.adapter.planexecutor.RunnableTaskExecutor;
import eu.melodic.upperware.adapter.plangenerator.model.AdapterRequirement;
import eu.melodic.upperware.adapter.plangenerator.tasks.NodeTask;
import lombok.extern.slf4j.Slf4j;
import org.activeeon.morphemic.model.NodeCandidate;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
......@@ -18,6 +16,9 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import static org.activeeon.morphemic.model.NodeCandidate.NodeCandidateTypeEnum.EDGE;
@Slf4j
public class NodeTaskExecutor extends RunnableTaskExecutor<AdapterRequirement> {
......@@ -45,6 +46,10 @@ public class NodeTaskExecutor extends RunnableTaskExecutor<AdapterRequirement> {
log.info("NodeTaskExecutor->create: [application id: {}] adding BYON node", applicationId);
addBYONNode(taskBody);
break;
case EDGE:
log.info("NodeTaskExecutor->create: [application id: {}] adding EDGE node", applicationId);
addEDGENode(taskBody);
break;
}
}
catch (RuntimeException e) {
......@@ -94,6 +99,21 @@ public class NodeTaskExecutor extends RunnableTaskExecutor<AdapterRequirement> {
log.info("NodeTaskExecutor->addBYONNode: [application id: {}] addByonNodes status= {}", applicationId, status);
}
private void addEDGENode(AdapterRequirement taskBody) {
String edgeId = proactiveClientServiceForAdapter.getEdgeNodeList(applicationId).stream()
.filter(edgeNode -> edgeNode.getNodeCandidate().getId().equals(taskBody.getNodeCandidate().getId()))
.findFirst()
.orElseThrow(() -> new AdapterException(String.format("Could not find EDGE with associated NodeCandidate id=%s", taskBody.getNodeCandidate().getId())))
.getId();
final Map<String, String> edgeIdPerComponent = Collections.singletonMap(edgeId,
taskBody.getTaskName());
log.info("NodeTaskExecutor->addEDGENode: [application id: {}] ProActive edgeIdPerComponent= {}", applicationId, edgeIdPerComponent);
int status = proactiveClientServiceForAdapter.addEdgeNodes(edgeIdPerComponent, applicationId);
log.info("NodeTaskExecutor->addEDGENode: [application id: {}] addEDGENodes status= {}", applicationId, status);
}
@Override
public void delete(AdapterRequirement taskBody) {
try {
......
......@@ -48,7 +48,8 @@ public class RequirementsConverter implements ModelConverter<DeploymentInstanceM
private void clearNodeCandidate(NodeCandidate nodeCandidate) {
//clear NodeCandidate from unnecessary Cloud in case of BYON
if (nodeCandidate != null && NodeCandidate.NodeCandidateTypeEnum.BYON.equals(nodeCandidate.getNodeCandidateType())) {
if (nodeCandidate != null && NodeCandidate.NodeCandidateTypeEnum.BYON.equals(nodeCandidate.getNodeCandidateType()) ||
(nodeCandidate != null && NodeCandidate.NodeCandidateTypeEnum.EDGE.equals(nodeCandidate.getNodeCandidateType()))) {
nodeCandidate.setCloud(null);
}
}
......
......@@ -173,7 +173,7 @@
<dependency>
<groupId>cloud.morphemic.connectors</groupId>
<artifactId>proactive_client</artifactId>
<version>2.0-SNAPSHOT</version>
<version>2.1-SNAPSHOT</version>
</dependency>
</dependencies>
......
......@@ -1770,63 +1770,6 @@
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
"dev": true
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"optional": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"optional": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"optional": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"optional": true
},
"loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"ssri": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
......@@ -1835,28 +1778,6 @@
"requires": {
"minipass": "^3.1.1"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.8.3",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz",
"integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
}
}
}
},
......@@ -11542,6 +11463,87 @@
}
}
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.8.3",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz",
"integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"optional": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"optional": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"optional": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"optional": true
},
"loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"vue-router": {
"version": "4.0.11",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.11.tgz",
......
......@@ -7,7 +7,7 @@
<parent>
<artifactId>upperware</artifactId>
<groupId>org.ow2.paasage</groupId>
<version>5.0.0-SNAPSHOT</version>
<version>4.5.0-SNAPSHOT</version>
</parent>
<groupId>eu.melodic</groupId>
......@@ -17,7 +17,7 @@
<properties>
<java.version>1.8</java.version>
<cdo.version>3.1.0-SNAPSHOT</cdo.version>
<upperware.version>5.0.0-SNAPSHOT</upperware.version>
<upperware.version>4.5.0-SNAPSHOT</upperware.version>
<!--DOCKER plugin properties-->
<docker.imageName>gui-backend</docker.imageName>
</properties>
......@@ -118,10 +118,22 @@
<dependency>
<groupId>cloud.morphemic.connectors</groupId>
<artifactId>proactive_client</artifactId>
<version>2.5-SNAPSHOT</version>
<version>2.5-20220421.141237-9</version>
</dependency>
<dependency>
<groupId>org.ow2.paasage</groupId>
<artifactId>melodic-commons</artifactId>
</dependency>
<dependency>
<groupId>org.activeeon</groupId>
<artifactId>scheduling-abstraction-layer</artifactId>
<version>4.5-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
......
package eu.melodic.upperware.guibackend.communication.proactive;
import cloud.morphemic.connectors.proactive.IProactiveClientServiceConnector;
import org.activeeon.morphemic.model.*;
import java.util.List;
......@@ -17,8 +18,12 @@ public interface ProactiveClientServiceGUI extends IProactiveClientServiceConnec
List<Location> getAllLocation();
EdgeNode registerNewEdgeNode(EdgeDefinition edgeDefinition, String jobId);
ByonNode registerNewByonNode(ByonDefinition byonNodeDefinition, String jobId, boolean automate);
List<EdgeNode> getEdgeNodeList(String jobId);
List<ByonNode> getByonNodeList(String jobId);
List<Job> getAllJobs();
......
package eu.melodic.upperware.guibackend.communication.proactive;
import cloud.morphemic.connectors.proactive.ProactiveClientServiceConnector;
import lombok.extern.slf4j.Slf4j;
import org.activeeon.morphemic.PAGateway;
import org.activeeon.morphemic.model.*;
......@@ -40,11 +41,21 @@ public class ProactiveClientServiceGUIImpl extends ProactiveClientServiceConnect
return getPAGateway().map(PAGateway::getLocationList).orElse(Collections.emptyList());
}
@Override
public EdgeNode registerNewEdgeNode(EdgeDefinition edgeDefinition, String jobId) {
return getPAGateway().map(paGateway -> paGateway.registerNewEdgeNode(edgeDefinition,jobId)).orElse(null);
}
@Override
public ByonNode registerNewByonNode(ByonDefinition byonNodeDefinition, String jobId, boolean automate) {
return getPAGateway().map(paGateway -> paGateway.registerNewByonNode(byonNodeDefinition, jobId, automate)).orElse(null);
}
@Override
public List<EdgeNode> getEdgeNodeList(String jobId) {
return getPAGateway().map(paGateway -> paGateway.getEdgeNodeList(jobId)).orElse(Collections.emptyList());
}
@Override
public List<ByonNode> getByonNodeList(String jobId) {
return getPAGateway().map(paGateway -> paGateway.getByonNodeList(jobId)).orElse(Collections.emptyList());
......
package eu.melodic.upperware.guibackend.controller.edge;
import eu.melodic.upperware.guibackend.service.edge.EdgeService;
import eu.passage.upperware.commons.model.edge.EdgeDefinition;
import eu.passage.upperware.commons.model.edge.EdgeEnums;
import eu.passage.upperware.commons.model.edge.EdgeNode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/auth/edge")
@Slf4j
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class EdgeController {
private EdgeService edgeService;
@GetMapping()
@ResponseStatus(HttpStatus.OK)
public List<EdgeDefinition> getEdgeDefinitionList() {
log.info("GET request for Edge definitions list");
return edgeService.getEdgeDefList(true).orElseGet(ArrayList::new);
}
@PostMapping()
@ResponseStatus(HttpStatus.CREATED)
public EdgeDefinition createEdgeDefinition(@RequestBody EdgeDefinition newEdgeDefinitionRequest) {
log.info("POST request for new Edge definition with name: {}", newEdgeDefinitionRequest.getName());
EdgeDefinition newEdgeDefinition = edgeService.createEdgeDef(newEdgeDefinitionRequest);
log.info("New Edge definition with name: {} and id: {} successfully added to configuration", newEdgeDefinition.getName(), newEdgeDefinition.getId());
return newEdgeDefinition;
}
@GetMapping("/{EdgeDefinitionId}")
@ResponseStatus(HttpStatus.OK)
public EdgeDefinition getEdgeDefinition(@PathVariable(value = "EdgeDefinitionId") int edgeDefinitionId) {
log.info("GET request for Edge definition with id {}", edgeDefinitionId);
return edgeService.getEdgeDef(edgeDefinitionId);
}
@DeleteMapping("/{EdgeDefinitionId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteEdgeDefinition(@PathVariable(value = "EdgeDefinitionId") int edgeDefinitionId) {
log.info("DELETE request for Edge definition with id {}", edgeDefinitionId);
edgeService.deleteEdgeDef(edgeDefinitionId);
log.info("Edge definition with id {} successfully deleted", edgeDefinitionId);
}
@PutMapping("/{EdgeDefinitionId}")
@ResponseStatus(HttpStatus.CREATED)
public EdgeDefinition updateEdgeDefinition(@PathVariable(value = "EdgeDefinitionId") int edgeDefinitionId,
@RequestBody EdgeDefinition edgeDefinitionToUpdate) {
log.info("PUT request for Edge definition with id {}", edgeDefinitionId);
EdgeDefinition edgeDefinition = edgeService.updateEdgeDef(edgeDefinitionId, edgeDefinitionToUpdate);
log.info("Edge definition with id {} successfully updated", edgeDefinitionId);
return edgeDefinition;
}
@PostMapping("/proactive/{EdgeDefinitionId}")
@ResponseStatus(HttpStatus.CREATED)
public eu.passage.upperware.commons.model.edge.EdgeNode createEdgeNode(@PathVariable(value = "EdgeDefinitionId") int EdgeDefinitionId, @RequestParam(value = "applicationId") String applicationId,
@RequestParam(value = "automate") boolean automate) {
log.info("POST request for creating new Edge node from Edge definition with id {} and for application id {}", EdgeDefinitionId, applicationId);
final eu.passage.upperware.commons.model.edge.EdgeNode edgeNode = edgeService.createEdgeNode(EdgeDefinitionId, applicationId);
log.info("Edge node with id {} successfully added to Proactive", edgeNode.getId());
return edgeNode;
}
@GetMapping("/cloudiator") // TODO: change to "proactive", but also in frontend
@ResponseStatus(HttpStatus.OK)
public List<EdgeNode> getEdgeNodesListFromProactive() {
log.info("GET request for edge nodes available in Proactive");
return edgeService.getAllEdgeNodesList();
}
@GetMapping("/enum")
@ResponseStatus(HttpStatus.OK)
public EdgeEnums getEdgeEnums() {
log.info("GET request for Edge enums");
return edgeService.getEdgeEnums();
}
}
package eu.melodic.upperware.guibackend.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class EdgeDefinitionNotFoundException extends RuntimeException {
public EdgeDefinitionNotFoundException(long edgeDefinitionId) {
super(String.format("Edge definition with id = %d not found", edgeDefinitionId));
}
}
......@@ -37,7 +37,7 @@ public class DeploymentMapper {
.api(mapApiToRequest(cloudDefinition.getApi()))
.credential(mapCredentialToRequest(cloudDefinition.getCredential()))
.endpoint(StringUtils.isBlank(cloudDefinition.getEndpoint().trim()) ? null : cloudDefinition.getEndpoint())
.id(RandomStringUtils.random(16, true, true))
.id(RandomStringUtils.random(8, true, true))
.build()).collect(Collectors.toList());
}
......
package eu.melodic.upperware.guibackend.service.edge;
import eu.passage.upperware.commons.model.edge.EdgeDefinition;
import eu.passage.upperware.commons.model.internal.IpAddress;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class EdgeIdCreatorService {
public void addIdsForEdgeDefinition(EdgeDefinition edgeDefinition, List<EdgeDefinition> edgeDefinitionsList) {
// index for edgeDefinition
long lastId = edgeDefinitionsList.stream()
.map(EdgeDefinition::getId)
.max(Long::compareTo)
.orElse(0L);
edgeDefinition.setId(lastId + 1);
// index for LoginCredential
long lastIndexForLoginCredential = edgeDefinitionsList.stream()
.map(edgeDef -> edgeDef.getLoginCredential().getId())
.max(Long::compareTo)
.orElse(0L);
edgeDefinition.getLoginCredential().setId(lastIndexForLoginCredential + 1);
// index for each IpAddress
long lastIndexForIpAddress = findLastIndexForIpAddress(edgeDefinitionsList);
for (int i = 0; i < edgeDefinition.getIpAddresses().size(); i++) {
edgeDefinition.getIpAddresses().get(i)
.setId(lastIndexForIpAddress + 1 + i);
}
// index for NodeProperties
long lastindexForNodeProperties = edgeDefinitionsList.stream()
.map(edgeDef -> edgeDef.getNodeProperties().getId())
.max(Long::compareTo)
.orElse(0L);
edgeDefinition.getNodeProperties().setId(lastindexForNodeProperties + 1);
// index for OperatingSystem
long lastIndexForOS = edgeDefinitionsList.stream()
.map(edgeDef -> edgeDef.getNodeProperties().getOperatingSystem().getId())
.max(Long::compareTo)
.orElse(0L);