Skip to content

Commit

Permalink
Merge branch develop to master
Browse files Browse the repository at this point in the history
  • Loading branch information
ludovicianul committed Jul 27, 2015
2 parents ca5f512 + 5ee95cf commit 05951a9
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 160 deletions.
89 changes: 51 additions & 38 deletions src/main/java/com/endockin/commandante/resource/FleetResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,49 +20,62 @@
@RequestMapping("/api/fleet")
public class FleetResource {

@Autowired
private SchedulerService schedulerService;
@Autowired
private SchedulerService schedulerService;

@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Fleet>> getAll() {
try {
List<Fleet> fleets = schedulerService.findAll();
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Fleet>> getAll() {
try {
List<Fleet> fleets = schedulerService.findAll();

return new ResponseEntity<>(fleets, HttpStatus.OK);
} catch (SchedulerServiceException ex) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
return new ResponseEntity<>(fleets, HttpStatus.OK);
} catch (SchedulerServiceException ex) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@RequestMapping(value = "/{id}", method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Fleet> get(@PathVariable String id) {
try {
Fleet fleet = schedulerService.find(id);
return new ResponseEntity<>(fleet, HttpStatus.OK);
} catch (SchedulerServiceException ex) {
if (SchedulerServiceException.Type.NOT_FOUND.equals(ex.getType())) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Fleet> get(@PathVariable String id) {
try {
Fleet fleet = schedulerService.find(id);
return new ResponseEntity<>(fleet, HttpStatus.OK);
} catch (SchedulerServiceException ex) {
if (SchedulerServiceException.Type.NOT_FOUND.equals(ex.getType())) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}

return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@RequestMapping(method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Fleet> postDockerShip(@RequestBody DockerFleet fleet) {
//TODO create custom deserializer for ship type do not use explicit docker ship
try {
return new ResponseEntity<>(schedulerService.schedule(fleet), HttpStatus.OK);
} catch (SchedulerServiceException ex) {
if (ex.getType() == SchedulerServiceException.Type.ALREADY_EXISTS) {
return new ResponseEntity<>(HttpStatus.CONFLICT);
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> delete(@PathVariable String id) {
try {
schedulerService.delete(id);
return new ResponseEntity<>(HttpStatus.OK);
} catch (SchedulerServiceException ex) {
if (SchedulerServiceException.Type.NOT_FOUND.equals(ex.getType())) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}

return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Fleet> postDockerShip(@RequestBody DockerFleet fleet) {
// TODO create custom deserializer for ship type do not use explicit
// docker ship
try {
return new ResponseEntity<>(schedulerService.schedule(fleet),
HttpStatus.OK);
} catch (SchedulerServiceException ex) {
if (ex.getType() == SchedulerServiceException.Type.ALREADY_EXISTS) {
return new ResponseEntity<>(HttpStatus.CONFLICT);
}

return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}

}
Original file line number Diff line number Diff line change
@@ -1,131 +1,155 @@
package com.endockin.commandante.service.impl.scheduler.marathon;

import com.endockin.commandante.model.Fleet;
import com.endockin.commandante.service.impl.scheduler.marathon.dto.AppDto;
import com.endockin.commandante.service.impl.scheduler.marathon.dto.AppsDto;
import com.endockin.commandante.service.impl.scheduler.marathon.dto.internal.MarathonApp;
import com.endockin.commandante.service.scheduler.SchedulerServiceException;
import com.endockin.commandante.service.scheduler.SchedulerService;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.http.HttpStatus;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import com.endockin.commandante.model.Fleet;
import com.endockin.commandante.service.impl.scheduler.marathon.dto.AppDto;
import com.endockin.commandante.service.impl.scheduler.marathon.dto.AppsDto;
import com.endockin.commandante.service.impl.scheduler.marathon.dto.internal.MarathonApp;
import com.endockin.commandante.service.scheduler.SchedulerService;
import com.endockin.commandante.service.scheduler.SchedulerServiceException;

@Service
public class MarathonSchedulerService implements SchedulerService {

//TODO: determine URL based on service discovery instead of hardcoding.
private static final String MARATHON_ROOT = "http://rocj-inolab-d01:8080";
private static final MarathonVersion MARATHON_VERSION = MarathonVersion.V2;
private static final Logger LOG = LoggerFactory.getLogger(MarathonSchedulerService.class);

@Autowired
private MarathonConverter converter;

@Override
public Fleet schedule(Fleet ship) throws SchedulerServiceException {
try {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<MarathonApp> result = restTemplate.postForEntity(
getURI(MARATHON_ROOT, MarathonResource.APPS), converter.getMarathonApp(ship), MarathonApp.class);

return converter.getFleet(result.getBody());
} catch (RestClientException rce) {
handleRestClientException(rce);
return null;
}

}

@Override
public List<Fleet> findAll() throws SchedulerServiceException {
try {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<AppsDto> result = restTemplate.getForEntity(getURI(MARATHON_ROOT, MarathonResource.APPS),
AppsDto.class);

return result.getBody().getMarathonApps().stream().map(converter::getFleet).
collect(Collectors.toCollection(() -> new LinkedList<>()));
} catch (RestClientException rce) {
handleRestClientException(rce);
return null;
}

}

@Override
public Fleet find(String id) throws SchedulerServiceException {
try {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<AppDto> result = restTemplate.getForEntity(getURI(MARATHON_ROOT, MarathonResource.APPS) + "/" + id,
AppDto.class);

return converter.getFleet(result.getBody().getMarathonApp());
} catch (RestClientException rce) {
handleRestClientException(rce);
return null;
}
}

private static void handleRestClientException(RestClientException e) throws SchedulerServiceException {
if (e instanceof HttpStatusCodeException) {
HttpStatusCodeException hsce = (HttpStatusCodeException) e;
LOG.info("Marathon request failed with HttpStatusCodeException. \n" + hsce.getResponseBodyAsString());

if (hsce.getStatusCode() == HttpStatus.NOT_FOUND) {
throw new SchedulerServiceException("Ship does not exist.", SchedulerServiceException.Type.NOT_FOUND);
} else if (hsce.getStatusCode() == HttpStatus.CONFLICT) {
throw new SchedulerServiceException("Ship already exists.", SchedulerServiceException.Type.ALREADY_EXISTS);
}
}

LOG.warn("Unhandled RestClientException from Marathon.", e);
throw new SchedulerServiceException(e.getMessage(), SchedulerServiceException.Type.OTHER);
}

private enum MarathonResource {

APPS("/apps"), GROUPS("/groups"), TASKS("/tasks"), DEPLOYMENTS("/deployments"),
EVENT_SUBSCRIPTIONS("/eventSubscriptions"), QUEUE("/queue"), INFO("/info"), LEADER("/leader"),
PING("/ping"), LOGGING("/logging"), HELP("/help"), METRICS("/metrics");

private final String fragment;

MarathonResource(String fragment) {
this.fragment = fragment;
}

public String getFragment() {
return fragment;
}
}

private enum MarathonVersion {

V1("/v1"), V2("/v2");

private final String fragment;

MarathonVersion(String fragment) {
this.fragment = fragment;
}

public String getFragment() {
return fragment;
}

}

private static String getURI(String base, MarathonResource resource) {
return base + MARATHON_VERSION.getFragment() + resource.getFragment();
}
// TODO: determine URL based on service discovery instead of hardcoding.
private static final String MARATHON_ROOT = "http://rocj-inolab-d01:8080";
private static final MarathonVersion MARATHON_VERSION = MarathonVersion.V2;
private static final Logger LOG = LoggerFactory
.getLogger(MarathonSchedulerService.class);

@Autowired
private MarathonConverter converter;

@Override
public Fleet schedule(Fleet ship) throws SchedulerServiceException {
try {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<MarathonApp> result = restTemplate.postForEntity(
getURI(MARATHON_ROOT, MarathonResource.APPS),
converter.getMarathonApp(ship), MarathonApp.class);

return converter.getFleet(result.getBody());
} catch (RestClientException rce) {
handleRestClientException(rce);
return null;
}

}

@Override
public List<Fleet> findAll() throws SchedulerServiceException {
try {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<AppsDto> result = restTemplate
.getForEntity(getURI(MARATHON_ROOT, MarathonResource.APPS),
AppsDto.class);

return result.getBody().getMarathonApps().stream()
.map(converter::getFleet)
.collect(Collectors.toCollection(() -> new LinkedList<>()));
} catch (RestClientException rce) {
handleRestClientException(rce);
return null;
}

}

@Override
public Fleet find(String id) throws SchedulerServiceException {
try {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<AppDto> result = restTemplate.getForEntity(
getURI(MARATHON_ROOT, MarathonResource.APPS) + "/" + id,
AppDto.class);

return converter.getFleet(result.getBody().getMarathonApp());
} catch (RestClientException rce) {
handleRestClientException(rce);
return null;
}
}

@Override
public void delete(String id) throws SchedulerServiceException {
try {
RestTemplate restTemplate = new RestTemplate();
restTemplate.delete(getURI(MARATHON_ROOT, MarathonResource.APPS)
+ "/" + id, AppDto.class);
} catch (RestClientException rce) {
handleRestClientException(rce);
}
}

private static void handleRestClientException(RestClientException e)
throws SchedulerServiceException {
if (e instanceof HttpStatusCodeException) {
HttpStatusCodeException hsce = (HttpStatusCodeException) e;
LOG.info("Marathon request failed with HttpStatusCodeException. \n"
+ hsce.getResponseBodyAsString());

if (hsce.getStatusCode() == HttpStatus.NOT_FOUND) {
throw new SchedulerServiceException("Ship does not exist.",
SchedulerServiceException.Type.NOT_FOUND);
} else if (hsce.getStatusCode() == HttpStatus.CONFLICT) {
throw new SchedulerServiceException("Ship already exists.",
SchedulerServiceException.Type.ALREADY_EXISTS);
}
}

LOG.warn("Unhandled RestClientException from Marathon.", e);
throw new SchedulerServiceException(e.getMessage(),
SchedulerServiceException.Type.OTHER);
}

private enum MarathonResource {

APPS("/apps"), GROUPS("/groups"), TASKS("/tasks"), DEPLOYMENTS(
"/deployments"), EVENT_SUBSCRIPTIONS("/eventSubscriptions"), QUEUE(
"/queue"), INFO("/info"), LEADER("/leader"), PING("/ping"), LOGGING(
"/logging"), HELP("/help"), METRICS("/metrics");

private final String fragment;

MarathonResource(String fragment) {
this.fragment = fragment;
}

public String getFragment() {
return fragment;
}
}

private enum MarathonVersion {

V1("/v1"), V2("/v2");

private final String fragment;

MarathonVersion(String fragment) {
this.fragment = fragment;
}

public String getFragment() {
return fragment;
}

}

private static String getURI(String base, MarathonResource resource) {
return base + MARATHON_VERSION.getFragment() + resource.getFragment();
}

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package com.endockin.commandante.service.scheduler;

import com.endockin.commandante.model.Fleet;

import java.util.List;

import com.endockin.commandante.model.Fleet;

public interface SchedulerService {

Fleet schedule(Fleet fleet) throws SchedulerServiceException;
Fleet schedule(Fleet fleet) throws SchedulerServiceException;

List<Fleet> findAll() throws SchedulerServiceException;

List<Fleet> findAll() throws SchedulerServiceException;
Fleet find(String id) throws SchedulerServiceException;

Fleet find(String id) throws SchedulerServiceException;
void delete(String id) throws SchedulerServiceException;
}

0 comments on commit 05951a9

Please sign in to comment.