@SpringApplicationConfiguration(classes = AdminRunner.class)
@WebAppConfiguration
public class ResourceWebTest {
  private static Logger logger = LoggerFactory.getLogger(ResourceWebTest.class);

  private MediaType contentType =
      new MediaType(
          MediaType.APPLICATION_JSON.getType(),
          MediaType.APPLICATION_JSON.getSubtype(),
          Charset.forName("UTF-8"));

  @Autowired private WebApplicationContext wac;

  private MockMvc mockMvc;

  @Before
  public void setUp() {
    this.mockMvc = webAppContextSetup(this.wac).build();
  }

  @Test
  public void test_user_userid() throws Exception {
    String userId = "";

    this.mockMvc
        .perform(get("resource/{resourceId}", userId))
        .andExpect(status().isOk())
        .andExpect(content().contentType(contentType))
        .andExpect(jsonPath("$.name").value("jarry"));
  }
}
Ejemplo n.º 2
0
 @Test(
     groups = {"rest", "invoice"},
     dataProvider = "queryAndOrderAndPaginateInvoiceLines",
     dataProviderClass = InvoiceLineDataProvider.class)
 public void shouldFilterAndOrderAndPaginateInvoiceLines(
     HashMap<String, Object> i, String[] keys, String[] values) throws Exception {
   mockMvc
       .perform(
           get("/col/invoices/" + i.get("id") + "/lines")
               .headers(getHeaders())
               .param(keys[0], values[0])
               .param(keys[1], values[1])
               .param(keys[2], values[2])
               .param(keys[3], values[3]))
       .andExpect(status().isOk())
       .andExpect(
           content()
               .contentType(
                   new MediaType(
                       MediaType.APPLICATION_JSON.getType(),
                       MediaType.APPLICATION_JSON.getSubtype(),
                       Charset.forName("utf8"))))
       .andExpect(jsonPath("$.total", is(1)))
       .andExpect(jsonPath("$.elements", hasSize(1)))
       .andExpect(jsonPath("$.elements[0].id", is("0000000001030000000001030000000003")));
 }
/** @author ihamilto */
@Configuration
public class MockApplicationContext {

  public static final MediaType APPLICATION_JSON =
      new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype());

  public static final MediaType APPLICATION_JSON_UTF8 =
      new MediaType(
          MediaType.APPLICATION_JSON.getType(),
          MediaType.APPLICATION_JSON.getSubtype(),
          Charset.forName("utf8"));
}
Ejemplo n.º 4
0
/** Utility class for testing REST controllers. */
public class TestUtil {

  /** MediaType for JSON UTF8 */
  public static final MediaType APPLICATION_JSON_UTF8 =
      new MediaType(
          MediaType.APPLICATION_JSON.getType(),
          MediaType.APPLICATION_JSON.getSubtype(),
          Charset.forName("utf8"));

  /**
   * Convert an object to JSON byte array.
   *
   * @param object the object to convert
   * @return the JSON byte array
   * @throws IOException
   */
  public static byte[] convertObjectToJsonBytes(Object object) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

    JavaTimeModule module = new JavaTimeModule();
    module.addSerializer(OffsetDateTime.class, JSR310DateTimeSerializer.INSTANCE);
    module.addSerializer(ZonedDateTime.class, JSR310DateTimeSerializer.INSTANCE);
    module.addSerializer(LocalDateTime.class, JSR310DateTimeSerializer.INSTANCE);
    module.addSerializer(Instant.class, JSR310DateTimeSerializer.INSTANCE);
    module.addDeserializer(LocalDate.class, JSR310LocalDateDeserializer.INSTANCE);
    mapper.registerModule(module);

    return mapper.writeValueAsBytes(object);
  }

  /**
   * Create a byte array with a specific size filled with specified data.
   *
   * @param size the size of the byte array
   * @param data the data to put in the byte array
   */
  public static byte[] createByteArray(int size, String data) {
    byte[] byteArray = new byte[size];
    for (int i = 0; i < size; i++) {
      byteArray[i] = Byte.parseByte(data, 2);
    }
    return byteArray;
  }
}
Ejemplo n.º 5
0
  /**
   * 发送post请求返回字符串
   *
   * @param url post-URL:
   * @param postData post的数据
   * @return 返回post请求响应的数据
   */
  public static String postUrl(String url, String postData) {
    RestTemplate restTemplate = new RestTemplate();
    HttpHeaders headers = new HttpHeaders();
    MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
    headers.setContentType(type);
    headers.add("Accept", MediaType.APPLICATION_JSON.toString());
    HttpEntity<String> formEntity = new HttpEntity<String>(postData, headers);

    return restTemplate.postForObject(url, formEntity, String.class);
  }
 @Test
 public void testCommenceWithEmptyAccept() throws Exception {
   entryPoint.commence(request, response, new BadCredentialsException("Bad"));
   assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
   assertEquals(
       "{\"error\":\"unauthorized\",\"error_description\":\"Bad\"}",
       response.getContentAsString());
   assertTrue(
       MediaType.APPLICATION_JSON.isCompatibleWith(MediaType.valueOf(response.getContentType())));
   assertEquals(null, response.getErrorMessage());
 }
/** Utility class for testing REST controllers. */
public class TestUtil {

  /** MediaType for JSON UTF8 */
  public static final MediaType APPLICATION_JSON_UTF8 =
      new MediaType(
          MediaType.APPLICATION_JSON.getType(),
          MediaType.APPLICATION_JSON.getSubtype(),
          Charset.forName("utf8"));

  /**
   * Convert an object to JSON byte array.
   *
   * @param object the object to convert
   * @return the JSON byte array
   * @throws IOException
   */
  public static byte[] convertObjectToJsonBytes(Object object) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    return mapper.writeValueAsBytes(object);
  }
}
Ejemplo n.º 8
0
public class IntegrationTestUtil {

  public static final MediaType APPLICATION_JSON_UTF8 =
      new MediaType(
          MediaType.APPLICATION_JSON.getType(),
          MediaType.APPLICATION_JSON.getSubtype(),
          Charset.forName("utf8"));

  public static byte[] convertObjectToJsonBytes(Object object, JsonSerialize.Inclusion inclusion)
      throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(inclusion);
    return mapper.writeValueAsBytes(object);
  }

  public static <T> Object convertJsonBytesToObject(
      byte[] src, Class<T> classe, JsonSerialize.Inclusion inclusion) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(inclusion);
    return mapper.readValue(src, classe);
  }
}
Ejemplo n.º 9
0
public class TestUtil {

  /** MediaType for JSON UTF8 */
  public static final MediaType APPLICATION_JSON_UTF8 =
      new MediaType(
          MediaType.APPLICATION_JSON.getType(),
          MediaType.APPLICATION_JSON.getSubtype(),
          Charset.forName("utf8"));

  /**
   * Convert an object to JSON byte array.
   *
   * @param object the object to convert
   * @return the JSON byte array
   * @throws IOException
   */
  public static byte[] convertObjectToJsonBytes(Object object) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    return mapper.writeValueAsBytes(object);
  }

  /**
   * Create a byte array with a specific size filled with specified data
   *
   * @param size
   * @param data
   * @return
   */
  public static byte[] createByteArray(int size, String data) {
    byte[] byteArray = new byte[size];
    for (int i = 0; i < size; i++) {
      byteArray[i] = Byte.parseByte(data, 2);
    }
    return byteArray;
  }
}
Ejemplo n.º 10
0
 @Test(
     groups = {"rest", "invoice"},
     dataProvider = "persistedInvoice",
     dataProviderClass = InvoiceDataProvider.class)
 public void shouldListAllInvoiceLines(HashMap<String, Object> i, HashMap<String, Object> c)
     throws Exception {
   mockMvc
       .perform(get("/col/invoices/" + i.get("id") + "/lines").headers(getHeaders()))
       .andExpect(status().isOk())
       .andExpect(
           content()
               .contentType(
                   new MediaType(
                       MediaType.APPLICATION_JSON.getType(),
                       MediaType.APPLICATION_JSON.getSubtype(),
                       Charset.forName("utf8"))))
       .andExpect(jsonPath("$.total", is(5)))
       .andExpect(jsonPath("$.elements", hasSize(5)))
       .andExpect(jsonPath("$.elements[0].id", is("0000000001010000000001010000000001")))
       .andExpect(jsonPath("$.elements[1].id", is("0000000001020000000001020000000002")))
       .andExpect(jsonPath("$.elements[2].id", is("0000000001030000000001030000000003")))
       .andExpect(jsonPath("$.elements[3].id", is("0000000001040000000001040000000004")))
       .andExpect(jsonPath("$.elements[4].id", is("0000000001050000000001050000000005")));
 }
  @Test
  public void headers() throws Exception {
    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
    httpHeaders.put("foo", Arrays.asList("bar", "baz"));
    this.builder.headers(httpHeaders);

    MockHttpServletRequest request = this.builder.buildRequest(this.servletContext);
    List<String> headers = Collections.list(request.getHeaders("foo"));

    assertEquals(2, headers.size());
    assertEquals("bar", headers.get(0));
    assertEquals("baz", headers.get(1));
    assertEquals(MediaType.APPLICATION_JSON.toString(), request.getHeader("Content-Type"));
  }
 private void validateResponse(final String responseBody, final MediaType mediaType) {
   if (responseBody != null && !responseBody.isEmpty()) {
     if (mediaType.getSubtype().equals(MediaType.APPLICATION_JSON.getSubtype())) {
       if (responseBody.contains("description") && responseBody.contains("code")) {
         String errorCode = extractCodeFromJson(responseBody);
         String errorDiscription = extractDescriptionFromJson(responseBody);
         LOGGER.info("errorCode : " + errorCode);
         LOGGER.info("errorDiscription : " + errorDiscription);
         throw new ResponseException(errorDiscription, errorCode);
       }
     } else {
       // TODO
       return;
     }
   }
 }
  @Override
  public boolean hasError(ClientHttpResponse response) throws IOException {
    // checkResponse(response); this is only for debugging purpose

    if (!response.getStatusCode().equals(HttpStatus.OK)) {
      throw new ResponseException(
          "Invalid request, returned with http status " + response.getStatusCode());
    } else if (!supportedMediaTypes.contains(response.getHeaders().getContentType().getSubtype())) {
      throw new ResponseException(
          "Invalid response, contents must be in either "
              + MediaType.APPLICATION_JSON.getSubtype()
              + " or "
              + MediaType.APPLICATION_XML.getSubtype()
              + ", but was "
              + response.getHeaders().getContentType().getSubtype());
    }
    return false;
  }
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@TransactionConfiguration(defaultRollback = true)
@Transactional
public class UserControllerTests {

  @Autowired private WebApplicationContext wac;

  private RestTemplate restTemplate;
  private int userId = 5;
  private String jsonDateFormatPattern = "yyyy-MM-dd HH:mm:ss";
  private MockRestServiceServer mockServer;
  private MockMvc mockMvc;
  private MediaType applicationJsonMediaType =
      new MediaType(
          MediaType.APPLICATION_JSON.getType(),
          MediaType.APPLICATION_JSON.getSubtype(),
          Charset.forName("utf8"));
  private MediaType vndErrorMediaType = MediaType.parseMediaType("application/vnd.error");

  @Before
  public void setup() {
    List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
    converters.add(new StringHttpMessageConverter());
    converters.add(new MappingJackson2HttpMessageConverter());

    this.restTemplate = new RestTemplate();
    this.restTemplate.setMessageConverters(converters);

    this.mockServer = MockRestServiceServer.createServer(this.restTemplate);
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
  }

  @Test
  public void testLoadingUserCustomers() throws Exception {
    this.mockMvc
        .perform(get("/users/" + userId + "/customers"))
        .andExpect(status().isOk())
        .andExpect(content().contentType(applicationJsonMediaType))
        .andExpect(
            jsonPath("$", hasSize(5))) // how many customers are seeded in the schema.sql file? 5.
        .andExpect(jsonPath("$[0].firstName", is("Rossen")));
  }

  @Test
  public void testDeletingAUser() throws Exception {

    mockMvc.perform(delete("/users/{userId}", userId)).andExpect(status().isNotFound());

    mockMvc.perform(get("/users/{userId}", userId)).andExpect(status().isNotFound());
  }

  @Test
  public void testCreateCustomer() throws Exception {

    long now = System.currentTimeMillis();
    String f = "Joe", l = "Doe";

    String jsonOfJoeDoe =
        "{ \"signupDate\":" + now + ",\"firstName\":\"" + f + "\",\"lastName\":\"" + l + "\"}";

    MvcResult mvcResult =
        mockMvc
            .perform(
                post("/users/{userId}/customers", userId)
                    .accept(applicationJsonMediaType)
                    .content(jsonOfJoeDoe)
                    .contentType(this.applicationJsonMediaType))
            .andExpect(status().isCreated())
            .andExpect(content().contentType(this.applicationJsonMediaType))
            .andReturn();

    mockServer.verify();

    String locationUri = mvcResult.getResponse().getHeader("Location");
    Assert.assertTrue(locationUri.contains("/users/" + userId + "/customers/"));
  }

  @Test
  public void testLoadingACustomerThatDoesNotExist() throws Exception {
    this.mockMvc
        .perform(get("/users/" + 5 + "/customers/" + 24022).accept(this.applicationJsonMediaType))
        .andExpect(status().isNotFound())
        .andExpect(content().contentType(this.vndErrorMediaType));
  }

  @Test
  public void testLoadingAUserThatDoesNotExist() throws Exception {
    this.mockMvc
        .perform(get("/users/" + 400).accept(this.applicationJsonMediaType))
        .andExpect(status().isNotFound())
        .andExpect(content().contentType(this.vndErrorMediaType));
  }

  @Test
  public void testLoadingAUser() throws Exception {

    DateFormat dateFormat = new SimpleDateFormat(jsonDateFormatPattern);
    int userId = 5;
    Date date = dateFormat.parse("2013-06-02 15:33:51");
    this.mockMvc
        .perform(get("/users/" + userId).accept(this.applicationJsonMediaType))
        .andExpect(status().isOk())
        .andExpect(content().contentType(applicationJsonMediaType))
        .andExpect(jsonPath("$.id", is(userId)))
        .andExpect(jsonPath("$.firstName", is("Josh")))
        .andExpect(jsonPath("$.password", is("cowbell")))
        .andExpect(jsonPath("$.signupDate", is(date.getTime())))
        .andExpect(jsonPath("$.lastName", is("Long")));
  }
}
/**
 * Abstract implementation of the CloudControllerClient intended to serve as the base for v1 and v2
 * implementations.
 *
 * @author Ramnivas Laddad
 * @author A.B.Srinivasan
 * @author Jennifer Hickey
 * @author Dave Syer
 * @author Thomas Risberg
 */
public abstract class AbstractCloudControllerClient implements CloudControllerClient {

  private static final String AUTHORIZATION_HEADER_KEY = "Authorization";
  private static final String PROXY_USER_HEADER_KEY = "Proxy-User";

  protected static final MediaType JSON_MEDIA_TYPE =
      new MediaType(
          MediaType.APPLICATION_JSON.getType(),
          MediaType.APPLICATION_JSON.getSubtype(),
          Charset.forName("UTF-8"));

  // This map only contains framework/runtime mapping for frameworks that we actively support
  private static Map<String, Integer> FRAMEWORK_DEFAULT_MEMORY =
      new HashMap<String, Integer>() {
        {
          put("spring", 512);
          put("lift", 512);
          put("grails", 512);
          put("java_web", 512);
        }
      };

  private static final int DEFAULT_MEMORY = 256;

  private static final int FILES_MAX_RETRIES = 10;

  private static final String LOGS_LOCATION = "logs";

  private RestTemplate restTemplate;

  private URL cloudControllerUrl;

  protected RestUtil restUtil;

  protected CloudCredentials cloudCredentials;

  protected URL authorizationEndpoint;

  protected String token;

  protected List<String> freeApplicationPlans = Arrays.asList("free");

  public AbstractCloudControllerClient(
      URL cloudControllerUrl,
      RestUtil restUtil,
      CloudCredentials cloudCredentials,
      URL authorizationEndpoint,
      HttpProxyConfiguration httpProxyConfiguration) {
    Assert.notNull(cloudControllerUrl, "CloudControllerUrl cannot be null");
    Assert.notNull(restUtil, "RestUtil cannot be null");
    this.restUtil = restUtil;
    this.cloudCredentials = cloudCredentials;
    if (cloudCredentials != null && cloudCredentials.getToken() != null) {
      this.token = cloudCredentials.getToken();
    }
    this.cloudControllerUrl = cloudControllerUrl;
    if (authorizationEndpoint != null) {
      this.authorizationEndpoint =
          determineAuthorizationEndPointToUse(authorizationEndpoint, cloudControllerUrl);
    } else {
      this.authorizationEndpoint = null;
    }
    this.restTemplate = restUtil.createRestTemplate(httpProxyConfiguration);
    configureCloudFoundryRequestFactory(restTemplate);

    this.restTemplate.setErrorHandler(new ErrorHandler());
    this.restTemplate.setMessageConverters(getHttpMessageConverters());
  }

  protected URL determineAuthorizationEndPointToUse(
      URL authorizationEndpoint, URL cloudControllerUrl) {
    if (cloudControllerUrl.getProtocol().equals("http")
        && authorizationEndpoint.getProtocol().equals("https")) {
      try {
        URL newUrl =
            new URL(
                "http",
                authorizationEndpoint.getHost(),
                authorizationEndpoint.getPort(),
                authorizationEndpoint.getFile());
        return newUrl;
      } catch (MalformedURLException e) {
        // this shouldn't happen
        return authorizationEndpoint;
      }
    }
    return authorizationEndpoint;
  }

  public URL getCloudControllerUrl() {
    return this.cloudControllerUrl;
  }

  public List<CloudSpace> getSpaces() {
    ArrayList<CloudSpace> list = new ArrayList<CloudSpace>();
    return list;
  }

  public List<String> getApplicationPlans() {
    return Collections.unmodifiableList(freeApplicationPlans);
  }

  public int[] getApplicationMemoryChoices() {
    // TODO: Get it from cloudcontroller's 'info/resources' end point
    int[] generalChoices = new int[] {64, 128, 256, 512, 1024, 2048};
    int maxMemory = getInfo().getLimits().getMaxTotalMemory();

    int length = 0;
    for (int generalChoice : generalChoices) {
      if (generalChoice <= maxMemory) {
        length++;
      }
    }

    int[] result = new int[length];
    System.arraycopy(generalChoices, 0, result, 0, length);
    return result;
  }

  public int getDefaultApplicationMemory(String framework) {
    Integer memory = FRAMEWORK_DEFAULT_MEMORY.get(framework);
    if (memory == null) {
      return DEFAULT_MEMORY;
    }
    return memory;
  }

  public void updatePassword(String newPassword) {
    updatePassword(cloudCredentials, newPassword);
  }

  public void updateHttpProxyConfiguration(HttpProxyConfiguration httpProxyConfiguration) {
    ClientHttpRequestFactory requestFactory = restUtil.createRequestFactory(httpProxyConfiguration);
    restTemplate.setRequestFactory(requestFactory);
    configureCloudFoundryRequestFactory(restTemplate);
  }

  public void updateApplicationPlan(String appName, String applicationPlan) {
    // subclasses should override this method if they support application plans
  }

  public Map<String, String> getLogs(String appName) {
    String urlPath = getFileUrlPath();
    String instance = String.valueOf(0);
    return doGetLogs(urlPath, appName, instance);
  }

  public Map<String, String> getCrashLogs(String appName) {
    String urlPath = getFileUrlPath();
    CrashesInfo crashes = getCrashes(appName);
    TreeMap<Date, String> crashInstances = new TreeMap<Date, String>();
    for (CrashInfo crash : crashes.getCrashes()) {
      crashInstances.put(crash.getSince(), crash.getInstance());
    }
    String instance = crashInstances.get(crashInstances.lastKey());
    return doGetLogs(urlPath, appName, instance);
  }

  public String getFile(
      String appName, int instanceIndex, String filePath, int startPosition, int endPosition) {
    String urlPath = getFileUrlPath();
    Object appId = getFileAppId(appName);
    return doGetFile(urlPath, appId, instanceIndex, filePath, startPosition, endPosition);
  }

  public List<CloudDomain> getDomainsForOrg() {
    // subclasses that support this feature must override this
    throw new UnsupportedOperationException("Feature is not implemented for this version.");
  }

  public List<CloudDomain> getDomains() {
    // subclasses that support this feature must override this
    throw new UnsupportedOperationException("Feature is not implemented for this version.");
  }

  public void addDomain(String domainName) {
    // subclasses that support this feature must override this
    throw new UnsupportedOperationException("Feature is not implemented for this version.");
  }

  public void deleteDomain(String domainName) {
    // subclasses that support this feature must override this
    throw new UnsupportedOperationException("Feature is not implemented for this version.");
  }

  public void removeDomain(String domainName) {
    // subclasses that support this feature must override this
  }

  public List<CloudRoute> getRoutes(String domainName) {
    // subclasses that support this feature must override this
    throw new UnsupportedOperationException("Feature is not implemented for this version.");
  }

  public void addRoute(String host, String domainName) {
    // subclasses that support this feature must override this
    throw new UnsupportedOperationException("Feature is not implemented for this version.");
  }

  public void deleteRoute(String host, String domainName) {
    // subclasses that support this feature must override this
    throw new UnsupportedOperationException("Feature is not implemented for this version.");
  }

  public void registerRestLogListener(RestLogCallback callBack) {
    if (getRestTemplate() instanceof LoggingRestTemplate) {
      ((LoggingRestTemplate) getRestTemplate()).registerRestLogListener(callBack);
    }
  }

  public void unRegisterRestLogListener(RestLogCallback callBack) {
    if (getRestTemplate() instanceof LoggingRestTemplate) {
      ((LoggingRestTemplate) getRestTemplate()).unRegisterRestLogListener(callBack);
    }
  }

  protected RestTemplate getRestTemplate() {
    return this.restTemplate;
  }

  protected String getUrl(String path) {
    return cloudControllerUrl + (path.startsWith("/") ? path : "/" + path);
  }

  protected abstract String getFileUrlPath();

  protected abstract Object getFileAppId(String appName);

  private void configureCloudFoundryRequestFactory(RestTemplate restTemplate) {
    ClientHttpRequestFactory requestFactory = restTemplate.getRequestFactory();
    restTemplate.setRequestFactory(new CloudFoundryClientHttpRequestFactory(requestFactory));
  }

  private List<HttpMessageConverter<?>> getHttpMessageConverters() {
    List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
    messageConverters.add(new ByteArrayHttpMessageConverter());
    messageConverters.add(new StringHttpMessageConverter());
    messageConverters.add(new ResourceHttpMessageConverter());
    messageConverters.add(new UploadApplicationPayloadHttpMessageConverter());
    messageConverters.add(getFormHttpMessageConverter());
    messageConverters.add(new MappingJacksonHttpMessageConverter());
    return messageConverters;
  }

  private FormHttpMessageConverter getFormHttpMessageConverter() {
    FormHttpMessageConverter formPartsMessageConverter = new CloudFoundryFormHttpMessageConverter();
    formPartsMessageConverter.setPartConverters(getFormPartsMessageConverters());
    return formPartsMessageConverter;
  }

  private List<HttpMessageConverter<?>> getFormPartsMessageConverters() {
    List<HttpMessageConverter<?>> partConverters = new ArrayList<HttpMessageConverter<?>>();
    StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
    stringConverter.setSupportedMediaTypes(Collections.singletonList(JSON_MEDIA_TYPE));
    stringConverter.setWriteAcceptCharset(false);
    partConverters.add(stringConverter);
    partConverters.add(new ResourceHttpMessageConverter());
    partConverters.add(new UploadApplicationPayloadHttpMessageConverter());
    return partConverters;
  }

  private class CloudFoundryClientHttpRequestFactory implements ClientHttpRequestFactory {

    private static final String LEGACY_TOKEN_PREFIX = "0408";
    private ClientHttpRequestFactory delegate;

    public CloudFoundryClientHttpRequestFactory(ClientHttpRequestFactory delegate) {
      this.delegate = delegate;
    }

    public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
      ClientHttpRequest request = delegate.createRequest(uri, httpMethod);
      if (token != null) {
        String header = token;
        if (!header.startsWith(LEGACY_TOKEN_PREFIX) && !header.toLowerCase().startsWith("bearer")) {
          header = "Bearer " + header; // UAA token without OAuth prefix
        }
        request.getHeaders().add(AUTHORIZATION_HEADER_KEY, header);
      }
      if (cloudCredentials != null && cloudCredentials.getProxyUser() != null) {
        request.getHeaders().add(PROXY_USER_HEADER_KEY, cloudCredentials.getProxyUser());
      }
      return request;
    }
  }

  public static class ErrorHandler extends DefaultResponseErrorHandler {
    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
      HttpStatus statusCode = response.getStatusCode();
      switch (statusCode.series()) {
        case CLIENT_ERROR:
          CloudFoundryException exception =
              new CloudFoundryException(statusCode, response.getStatusText());
          ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
          if (response.getBody() != null) {
            try {
              @SuppressWarnings("unchecked")
              Map<String, Object> map = mapper.readValue(response.getBody(), Map.class);
              exception.setDescription(CloudUtil.parse(String.class, map.get("description")));
            } catch (JsonParseException e) {
              exception.setDescription("Client error");
            } catch (IOException e) {
              exception.setDescription("Client error");
            }
          } else {
            exception.setDescription("Client error");
          }
          throw exception;
        case SERVER_ERROR:
          throw new HttpServerErrorException(statusCode, response.getStatusText());
        default:
          throw new RestClientException("Unknown status code [" + statusCode + "]");
      }
    }
  }

  public static class CloudFoundryFormHttpMessageConverter extends FormHttpMessageConverter {
    @Override
    protected String getFilename(Object part) {
      if (part instanceof UploadApplicationPayload) {
        return ((UploadApplicationPayload) part).getArchive().getFilename();
      }
      return super.getFilename(part);
    }
  }

  protected Map<String, String> doGetLogs(String urlPath, String appName, String instance) {
    Object appId = getFileAppId(appName);
    String logFiles = doGetFile(urlPath, appId, instance, LOGS_LOCATION, -1, -1);
    String[] lines = logFiles.split("\n");
    List<String> fileNames = new ArrayList<String>();
    for (String line : lines) {
      String[] parts = line.split("\\s");
      if (parts.length > 0 && parts[0] != null) {
        fileNames.add(parts[0]);
      }
    }
    Map<String, String> logs = new HashMap<String, String>(fileNames.size());
    for (String fileName : fileNames) {
      String logFile = LOGS_LOCATION + "/" + fileName;
      logs.put(logFile, doGetFile(urlPath, appId, instance, logFile, -1, -1));
    }
    return logs;
  }

  protected String doGetFile(
      String urlPath,
      Object app,
      int instanceIndex,
      String filePath,
      int startPosition,
      int endPosition) {
    return doGetFile(
        urlPath, app, String.valueOf(instanceIndex), filePath, startPosition, endPosition);
  }

  protected String doGetFile(
      String urlPath,
      Object app,
      String instance,
      String filePath,
      int startPosition,
      int endPosition) {
    Assert.isTrue(startPosition >= -1, "Invalid start position value: " + startPosition);
    Assert.isTrue(endPosition >= -1, "Invalid end position value: " + endPosition);
    Assert.isTrue(
        startPosition < 0 || endPosition < 0 || endPosition >= startPosition,
        "The end position ("
            + endPosition
            + ") can't be less than the start position ("
            + startPosition
            + ")");

    int start, end;
    if (startPosition == -1 && endPosition == -1) {
      start = 0;
      end = -1;
    } else {
      start = startPosition;
      end = endPosition;
    }

    final String range = "bytes=" + (start == -1 ? "" : start) + "-" + (end == -1 ? "" : end);

    // simple retry
    int tries = 0;
    String response = null;
    while (response == null) {
      tries++;
      try {
        response = doGetFileByRange(urlPath, app, instance, filePath, start, end, range);
      } catch (HttpServerErrorException e) {
        if (e.getStatusCode().equals(HttpStatus.SERVICE_UNAVAILABLE)) {
          if (tries > FILES_MAX_RETRIES) {
            throw e;
          }
        } else {
          throw e;
        }
      }
    }

    return response;
  }

  private String doGetFileByRange(
      String urlPath,
      Object app,
      String instance,
      String filePath,
      int start,
      int end,
      String range) {

    boolean supportsRanges = false;
    try {
      supportsRanges =
          getRestTemplate()
              .execute(
                  getUrl(urlPath),
                  HttpMethod.HEAD,
                  new RequestCallback() {
                    public void doWithRequest(ClientHttpRequest request) throws IOException {
                      request.getHeaders().set("Range", "bytes=0-");
                    }
                  },
                  new ResponseExtractor<Boolean>() {
                    public Boolean extractData(ClientHttpResponse response) throws IOException {
                      if (response.getStatusCode().equals(HttpStatus.PARTIAL_CONTENT)) {
                        return true;
                      }
                      return false;
                    }
                  },
                  app,
                  instance,
                  filePath);
    } catch (CloudFoundryException e) {
      if (e.getStatusCode().equals(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE)) {
        // must be a 0 byte file
        return "";
      } else {
        throw e;
      }
    }
    HttpHeaders headers = new HttpHeaders();
    if (supportsRanges) {
      headers.set("Range", range);
    }
    HttpEntity<Object> requestEntity = new HttpEntity<Object>(headers);
    ResponseEntity<String> responseEntity =
        getRestTemplate()
            .exchange(
                getUrl(urlPath),
                HttpMethod.GET,
                requestEntity,
                String.class,
                app,
                instance,
                filePath);
    String response = responseEntity.getBody();
    boolean partialFile = false;
    if (responseEntity.getStatusCode().equals(HttpStatus.PARTIAL_CONTENT)) {
      partialFile = true;
    }
    if (!partialFile && response != null) {
      if (start == -1) {
        return response.substring(response.length() - end);
      } else {
        if (start >= response.length()) {
          if (response.length() == 0) {
            return "";
          }
          throw new CloudFoundryException(
              HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE,
              "The starting position " + start + " is past the end of the file content.");
        }
        if (end != -1) {
          if (end >= response.length()) {
            end = response.length() - 1;
          }
          return response.substring(start, end + 1);
        } else {
          return response.substring(start);
        }
      }
    }
    return response;
  }
}
 static {
   supportedMediaTypes.add(MediaType.APPLICATION_JSON.getSubtype());
   supportedMediaTypes.add(MediaType.APPLICATION_XML.getSubtype());
 }
Ejemplo n.º 17
0
 @Override
 public final String getMime() {
   return MediaType.APPLICATION_JSON.toString();
 }
Ejemplo n.º 18
0
/**
 * Utility class for testing REST controllers.
 */
public class TestUtil {

    /** MediaType for JSON UTF8 */
    public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(
            MediaType.APPLICATION_JSON.getType(),
            MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));

    /**
     * Convert an object to JSON byte array.
     *
     * @param object
     *            the object to convert
     * @return the JSON byte array
     * @throws IOException
     */
    public static byte[] convertObjectToJsonBytes(Object object)
            throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        JavaTimeModule module = new JavaTimeModule();
        mapper.registerModule(module);

        return mapper.writeValueAsBytes(object);
    }

    /**
     * Create a byte array with a specific size filled with specified data.
     *
     * @param size the size of the byte array
     * @param data the data to put in the byte array
     * @return the JSON byte array
     */
    public static byte[] createByteArray(int size, String data) {
        byte[] byteArray = new byte[size];
        for (int i = 0; i < size; i++) {
            byteArray[i] = Byte.parseByte(data, 2);
        }
        return byteArray;
    }

    /**
     * A matcher that tests that the examined string represents the same instant as the reference datetime.
     */
    public static class ZonedDateTimeMatcher extends TypeSafeDiagnosingMatcher<String> {

        private final ZonedDateTime date;

        public ZonedDateTimeMatcher(ZonedDateTime date) {
            this.date = date;
        }

        @Override
        protected boolean matchesSafely(String item, Description mismatchDescription) {
            try {
                if (!date.isEqual(ZonedDateTime.parse(item))) {
                    mismatchDescription.appendText("was ").appendValue(item);
                    return false;
                }
                return true;
            } catch (DateTimeParseException e) {
                mismatchDescription.appendText("was ").appendValue(item)
                    .appendText(", which could not be parsed as a ZonedDateTime");
                return false;
            }

        }

        @Override
        public void describeTo(Description description) {
            description.appendText("a String representing the same Instant as ").appendValue(date);
        }
    }

    /**
     * Creates a matcher that matches when the examined string reprensents the same instant as the reference datetime
     * @param date the reference datetime against which the examined string is checked
     */
    public static ZonedDateTimeMatcher sameInstant(ZonedDateTime date) {
        return new ZonedDateTimeMatcher(date);
    }

}