Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

31 depens on #66

Merged
merged 3 commits into from
Jul 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Trampoline [![Twitter](https://img.shields.io/twitter/follow/espadrine.svg?style=social&logo=twitter&label=Follow)](https://twitter.com/TrampolineSB)
# Trampoline [![Twitter](https://img.shields.io/twitter/follow/espadrine.svg?style=social&logo=twitter&label=Follow)](https://twitter.com/TrampolineSB)


[![Build Status](https://travis-ci.org/stunstunstun/awesome-spring-boot.svg?branch=master)](https://travis-ci.org/stunstunstun/awesome-spring-boot) [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/Trampoline-springboot/Lobby)
Expand All @@ -13,7 +13,7 @@ Are you Admin Spring Boot locally? Are you **tired of that set of scripts**? Rel

The aim is to **help during the course of developing an application based on the paradigm of microservices with _Spring Boot_**. How? Easy, thanks to a **comfortable interface** you can **declare new microservices**, **start instances**, **restart** and **kill them**.

![Alt text](https://github.com/ErnestOrt/Trampoline/blob/master/TrampolineUI_3_13.png)
![Alt text](https://github.com/ErnestOrt/Trampoline/blob/master/TrampolineUI_3_14.png)

Also you will be able to:

Expand All @@ -25,7 +25,7 @@ Also you will be able to:
* See Git branch and last commit on instances
* Checkout branch, pull code and restart instances with a single mouse click
* Define microservices groups and launch them all with one click
* Monitor microservies deployed on other machines.
* Monitor microservies deployed on other machines

### Requirements

Expand All @@ -49,8 +49,12 @@ To Admin Spring Boot locally:

### FAQ

* How microservices groups are launched?

All microservices are launched secuantially, folowing the order specified, applying defined delay for each instance.

* Which build tools are Trampoline compatible with in my microservices?

You can use Apache Maven or Gradle Wrapper.

* Can I run it on any OS?
Expand Down
Binary file added TrampolineUI_3_14.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ public Microservice getInstanceInfo(@RequestParam(value="id") String id) throws

@RequestMapping(value= "/startinstance", method = RequestMethod.POST)
@ResponseBody
public void startInstance(@RequestParam(value="id") String id, @RequestParam(value="port") String port, @RequestParam(value="vmArguments") String vmArguments) throws CreatingSettingsFolderException, ReadingEcosystemException, RunningMicroserviceScriptException, SavingEcosystemException {
ecosystemManager.startInstance(id, port, vmArguments);
public void startInstance(@RequestParam(value="id") String id, @RequestParam(value="port") String port, @RequestParam(value="vmArguments") String vmArguments) throws CreatingSettingsFolderException, ReadingEcosystemException, RunningMicroserviceScriptException, SavingEcosystemException, InterruptedException {
ecosystemManager.startInstance(id, port, vmArguments, 0);
}

@RequestMapping(value= "/restartinstance", method = RequestMethod.POST)
@ResponseBody
public void restartInstance(@RequestParam(value="id") String id) throws CreatingSettingsFolderException, ReadingEcosystemException, SavingEcosystemException, ShuttingDownInstanceException {
public void restartInstance(@RequestParam(value="id") String id) throws CreatingSettingsFolderException, ReadingEcosystemException, SavingEcosystemException, ShuttingDownInstanceException, InterruptedException {
ecosystemManager.restartInstance(id);
}

Expand Down Expand Up @@ -106,7 +106,7 @@ public boolean checkPort(@RequestParam(value="port") int port) throws CreatingSe

@RequestMapping(value= "/startgroup", method = RequestMethod.POST)
@ResponseBody
public void startGroup(@RequestParam(value="id") String id) {
public void startGroup(@RequestParam(value="id") String id) throws InterruptedException {
ecosystemManager.startGroup(id);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Controller
Expand Down Expand Up @@ -99,8 +101,8 @@ public Microservice getMicroserviceInfo(@RequestParam(value="id") String id) thr

@RequestMapping(value= "/setmicroservicesgroup", method = RequestMethod.POST)
@ResponseBody
public void getMicroserviceInfo(@RequestParam(value="name") String name, @RequestParam(value="idsMicroservicesGroup[]") List<String> idsMicroservicesGroup) throws CreatingSettingsFolderException, ReadingEcosystemException, CreatingMicroserviceScriptException, SavingEcosystemException {
ecosystemManager.setMicroserviceGroup(name, idsMicroservicesGroup);
public void getMicroserviceInfo(@RequestParam(value="name") String name, @RequestParam(value="idsMicroservicesGroup[]") List<String> idsMicroservicesGroup, @RequestParam(value="delaysMicroservicesGroup[]") List<Integer> delaysMicroservicesGroup) throws CreatingSettingsFolderException, ReadingEcosystemException, CreatingMicroserviceScriptException, SavingEcosystemException {
ecosystemManager.setMicroserviceGroup(name, idsMicroservicesGroup, delaysMicroservicesGroup);
}

@RequestMapping(value= "/groupinfo", method = RequestMethod.POST)
Expand All @@ -111,9 +113,15 @@ public MicroserviceGroupInfo getGroupInfo(@RequestParam(value="id") String id) t

MicroserviceGroupInfo info = new MicroserviceGroupInfo();
info.setName(microservicesGroup.getName());

Map<String, Integer> delays = new HashMap<>();
for (int index = 0; index < microservicesGroup.getMicroservicesIds().size(); index++){
delays.put(microservicesGroup.getMicroservicesIds().get(index), microservicesGroup.getMicroservicesDelays().get(index));
}

info.setMicroservicesNames(microservices.stream()
.filter(m->microservicesGroup.getMicroservicesIds().contains(m.getId()))
.map(Microservice::getName)
.map(microservice -> microservice.getName() +" ["+delays.get(microservice.getId())+" sec]")
.collect(Collectors.toList()));
return info;
}
Expand Down Expand Up @@ -141,7 +149,13 @@ public void checkoutAndPull(@RequestParam(value="id") String id, @RequestParam(v
public void checkoutAndPullAndRestart(@RequestParam(value="id") String id, @RequestParam(value="branchName") String branchName) throws CreatingSettingsFolderException, ReadingEcosystemException, SavingEcosystemException, IOException, GitAPIException {
gitManager.checkoutAndPull(id, branchName);
List<String> intancesIds = ecosystemManager.getEcosystem().getInstances().stream().filter(i-> i.getMicroserviceId().equals(id)).map(Instance::getId).collect(Collectors.toList());
intancesIds.forEach(intancesId-> ecosystemManager.restartInstance(intancesId));
intancesIds.forEach(intancesId-> {
try {
ecosystemManager.restartInstance(intancesId);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}

@RequestMapping(value= "/git/config/save", method = RequestMethod.POST)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class MicroservicesGroup {
private String id;
private String name;
private List<String> microservicesIds;
private List<Integer> microservicesDelays;

public String getId() {
return id;
Expand All @@ -33,5 +34,11 @@ public void setMicroservicesIds(List<String> microservicesIds) {
this.microservicesIds = microservicesIds;
}

public List<Integer> getMicroservicesDelays() {
return microservicesDelays;
}

public void setMicroservicesDelays(List<Integer> microservicesDelays) {
this.microservicesDelays = microservicesDelays;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,13 @@ public void removeMicroservice(String idToBeDeleted) throws CreatingSettingsFold
fileManager.saveEcosystem(ecosystem);
}

public void setMicroserviceGroup(String name, List<String> idsMicroservicesGroup) {
public void setMicroserviceGroup(String name, List<String> idsMicroservicesGroup, List<Integer> delaysMicroservicesGroup) {
log.info("Creating group name: [{}] with microservices [{}]", name, idsMicroservicesGroup.stream().collect(Collectors.joining(",")));
MicroservicesGroup microservicesGroup = new MicroservicesGroup();
microservicesGroup.setId(UUID.randomUUID().toString());
microservicesGroup.setName(name);
microservicesGroup.setMicroservicesIds(idsMicroservicesGroup);
microservicesGroup.setMicroservicesDelays(delaysMicroservicesGroup);

Ecosystem ecosystem = fileManager.getEcosystem();
ecosystem.getMicroservicesGroups().add(microservicesGroup);
Expand All @@ -92,11 +93,13 @@ public void removeGroup(String id) {
fileManager.saveEcosystem(ecosystem);
}

public void startInstance(String id, String port, String vmArguments) throws CreatingSettingsFolderException, ReadingEcosystemException, RunningMicroserviceScriptException, SavingEcosystemException{
log.info("Starting instances id: [{}] port: [{}] vmArguments: [{}]", id, port, vmArguments);
public void startInstance(String id, String port, String vmArguments, Integer startingDelay) throws CreatingSettingsFolderException, ReadingEcosystemException, RunningMicroserviceScriptException, SavingEcosystemException, InterruptedException {
log.info("Starting instances id: [{}] port: [{}] vmArguments: [{}] startingDelay: [{}]", id, port, vmArguments, startingDelay);
Ecosystem ecosystem = fileManager.getEcosystem();

Microservice microservice = ecosystem.getMicroservices().stream().filter(m -> m.getId().equals(id)).findAny().get();
Thread.sleep(startingDelay*1000);
log.info("Launching script to start instances id: [{}]", id);
fileManager.runScript(microservice, ecosystem.getMavenBinaryLocation(), ecosystem.getMavenHomeLocation(), port, vmArguments);

Instance instance = new Instance();
Expand Down Expand Up @@ -150,24 +153,27 @@ private boolean isDeployed(Instance instance) {
return true;
}

public void startGroup(String id) {
public void startGroup(String id) throws InterruptedException {
log.info("Starting group id: [{}]", id);
MicroservicesGroup group = fileManager.getEcosystem().getMicroservicesGroups().stream().filter(g -> g.getId().equals(id)).findFirst().get();
Ecosystem ecosystem = fileManager.getEcosystem();
MicroservicesGroup group = ecosystem.getMicroservicesGroups().stream().filter(g -> g.getId().equals(id)).findFirst().get();

fileManager.getEcosystem().getMicroservices().stream()
.filter(m->group.getMicroservicesIds().contains(m.getId()))
.forEach(m->prepareMicroservice(m));
for(int index = 0; index < group.getMicroservicesIds().size(); index++){
int microserviceIndex = index;
Microservice microservice = ecosystem.getMicroservices().stream().filter(m->m.getId().equals(group.getMicroservicesIds().get(microserviceIndex))).findAny().get();
prepareMicroservice(microservice, group.getMicroservicesDelays().get(microserviceIndex));
}
}

private void prepareMicroservice(Microservice microservice) {
private void prepareMicroservice(Microservice microservice, Integer startingDelay) throws InterruptedException {
int port = Integer.parseInt(microservice.getDefaultPort());
boolean instanceStarted = false;
List<Instance> instances = fileManager.getEcosystem().getInstances();

while(!instanceStarted) {
final int portToBeLaunched = port;
if (PortsChecker.available(portToBeLaunched) && !instances.stream().anyMatch(i -> i.getPort().equals(String.valueOf(portToBeLaunched)))) {
startInstance(microservice.getId(), String.valueOf(port), "");
startInstance(microservice.getId(), String.valueOf(port), "", startingDelay);
instanceStarted = true;
}else{
port++;
Expand All @@ -192,12 +198,12 @@ public void updateMicroservice(String id, String pomLocation, String defaultPort
fileManager.saveEcosystem(ecosystem);
}

public void restartInstance(String instanceId) {
public void restartInstance(String instanceId) throws InterruptedException {
log.info("Restarting instance id: [{}]", instanceId);
Ecosystem ecosystem = fileManager.getEcosystem();
Instance instance = ecosystem.getInstances().stream().filter(i -> i.getId().equals(instanceId)).findFirst().get();
killInstance(instance.getId());
startInstance(instance.getMicroserviceId(), instance.getPort(), instance.getVmArguments());
startInstance(instance.getMicroserviceId(), instance.getPort(), instance.getVmArguments(), 0);
}

public void saveGitCred(String user, String pass) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.File;
import java.io.IOException;
import java.util.stream.Collectors;

import org.apache.commons.io.FileUtils;
import org.ernest.applications.trampoline.entities.BuildTools;
Expand Down Expand Up @@ -64,12 +65,21 @@ private void updateMicroservicesInformationStored(Ecosystem ecosystem) {
ecosystemChanged = createBuildTool(ecosystem, ecosystemChanged);
ecosystemChanged = createVersion(ecosystem, ecosystemChanged, currentVersion);
ecosystemChanged = createIp(ecosystem, ecosystemChanged);
ecosystemChanged = createGroupDelays(ecosystem, ecosystemChanged);

if(ecosystemChanged){
saveEcosystem(ecosystem);
}
}

private boolean createGroupDelays(Ecosystem ecosystem, boolean ecosystemChanged) {
if(ecosystem.getMicroservicesGroups().stream().anyMatch(i -> i.getMicroservicesDelays() == null)){
ecosystem.getMicroservicesGroups().stream().filter(i -> i.getMicroservicesDelays() == null).forEach(i -> i.setMicroservicesDelays(i.getMicroservicesIds().stream().map(s -> new Integer(0)).collect(Collectors.toList())));
ecosystemChanged = true;
}
return ecosystemChanged;
}

private boolean createIp(Ecosystem ecosystem, boolean ecosystemChanged) {
if(ecosystem.getInstances().stream().anyMatch(i -> i.getIp() == null)){
ecosystem.getInstances().stream().filter(i -> i.getIp() == null).forEach(i -> i.setIp("127.0.0.1"));
Expand Down
60 changes: 48 additions & 12 deletions trampoline/src/main/resources/static/v2/js/app/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,30 @@ function changeSelectedClass(element) {
}

function createGroup(){
idsMicroservicesGroup = [];
delaysMicroservicesGroup = [];

$( ".group-definition-ms" ).each(function( index ) {
idsMicroservicesGroup.push($( this ).data("id"));
delaysMicroservicesGroup.push($( this ).val());
});

$.ajax({
url : "/settings/setmicroservicesgroup",
type: "POST",
data : {name: $("#input-groupname").val(),
idsMicroservicesGroup: idsMicroservicesGroup,
delaysMicroservicesGroup: delaysMicroservicesGroup},
success: function(data, textStatus, jqXHR) {location.reload();},
error: function (request, status, error) {
$('.front-loading').hide();
showNotification('danger', "Error occurred when trying to create a group. Check Logs for more info");
}
});

}

function defineGroup(){
idsMicroservicesGroup = [];
$( ".microservice-group-form.btn-success" ).each(function( index ) {
idsMicroservicesGroup.push($( this ).data("id"));
Expand All @@ -21,21 +45,33 @@ function createGroup(){
$("#form-groupname").removeClass("has-error");
showNotification('danger', "You must select <b>at least two microservices</b> to register a group. <b>Remember to register microservices first</b>.");
}else{
$("#modal-microservice-information").modal("show");
$.ajax({
url : "/settings/setmicroservicesgroup",
type: "POST",
data : {name: $("#input-groupname").val(),
idsMicroservicesGroup: idsMicroservicesGroup},
success: function(data, textStatus, jqXHR) {location.reload();},
error: function (request, status, error) {
$('.front-loading').hide();
showNotification('danger', "Error occurred when trying to create a group. Check Logs for more info");
}
});
$("#title-group-definition").html($("#input-groupname").val());
$("#table-group-definition > tbody").html("");

$( ".microservice-group-form.btn-success" ).each(function( index ) {
$('#table-group-definition > tbody').append('<tr class="even gradeA"><td>'+$( this ).data("name")+'</td><td><input class="group-definition-ms" data-id="'+$( this ).data("id")+'" type="text" class="form-control border-input" value="0"/></td>'+
'<td>'+
'<input id="group-item-'+index+'" class="group-definition-ms-order" value="'+(index+1)+'" onchange="sortGroupRows()"/>'+
'</td></tr>');
});

$("#modal-group-definition").modal("show");
}
}

function sortGroupRows(){
var tb = $('#table-group-definition > tbody');
var rows = tb.find('tr');
rows.sort(function(a, b) {
console.log(a)
var keyA = $(a).find('.group-definition-ms-order').val();
var keyB = $(b).find('.group-definition-ms-order').val();
return keyA - keyB;
});
$.each(rows, function(index, row) {
tb.append(row);
});}

function setMavenInformation(){
if($("#input-mavenhomelocation").val() == ''){
$("#form-mavenhomelocation").addClass("has-error");
Expand Down
Loading