package org.opentosca.csarrepo.util; import java.io.File; import java.io.FileNotFoundException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation.Builder; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.media.multipart.FormDataBodyPart; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataMultiPart; import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.json.JSONArray; import org.json.JSONException; import org.opentosca.csarrepo.filesystem.FileSystem; import org.opentosca.csarrepo.model.CsarFile; public class WineryApiClient { private static final Logger LOGGER = LogManager.getLogger(WineryApiClient.class); private Client client; private String url; public WineryApiClient(URL url) { this.url = url.toExternalForm(); if (this.url.charAt(this.url.length() - 1) != '/') { this.url += "/"; } this.client = ClientBuilder.newClient(new ClientConfig().register(MultiPartFeature.class)); } public void uploadToWinery(CsarFile file) throws Exception { FileSystem fs = new FileSystem(); File f = fs.getFile(file.getHashedFile().getFilename()); if (f == null) { throw new FileNotFoundException(file.getName() + " not found"); } // build form data FormDataMultiPart multiPart = new FormDataMultiPart(); FormDataContentDisposition.FormDataContentDispositionBuilder dispositionBuilder = FormDataContentDisposition .name("file"); dispositionBuilder.fileName(file.getName()); dispositionBuilder.size(f.getTotalSpace()); FormDataContentDisposition formDataContentDisposition = dispositionBuilder.build(); multiPart.bodyPart(new FormDataBodyPart("file", f, MediaType.APPLICATION_OCTET_STREAM_TYPE) .contentDisposition(formDataContentDisposition)); Entity<FormDataMultiPart> entity = Entity.entity(multiPart, MediaType.MULTIPART_FORM_DATA_TYPE); // send request WebTarget target = client.target(this.url); Builder request = target.request(); request.accept("application/json"); Response response = request.post(entity); // handle response if (Status.NO_CONTENT.getStatusCode() == response.getStatus()) { return; } if (Status.BAD_REQUEST.getStatusCode() == response.getStatus()) { String json = response.readEntity(String.class); List<String> errors = this.parseErrorsJson(json); throw new Exception(StringUtils.join(errors)); } throw new Exception("failed to push to winery"); } public WineryCsarFileObject pullFromWinery(String id) throws Exception { // send request WebTarget target = client.target(this.url + "servicetemplates/" + id); Builder request = target.request(); request.accept("application/zip"); Response response = request.get(); if (Status.NOT_FOUND.getStatusCode() == response.getStatus()) { // 404 throw new Exception("No corresponding servicetemplate found"); } if (Status.OK.getStatusCode() == response.getStatus()) { // 200 try { InputStream stream = (InputStream) response.getEntity(); String filename = ""; Pattern regex = Pattern.compile("(?<=filename=\").*?(?=\")"); Matcher regexMatcher = regex.matcher(response.getHeaderString("Content-Disposition")); if (regexMatcher.find()) { filename = regexMatcher.group(); } return new WineryCsarFileObject(stream, filename); } catch (Exception e) { e.printStackTrace(); return null; } } // other status code throw new Exception("Error connecting to winery"); } public List<Servicetemplate> getServiceTemplates() throws Exception { // send request WebTarget target = client.target(this.url + "servicetemplates/"); Builder request = target.request(); request.accept("application/json"); Response response = request.get(); if (Status.NOT_FOUND.getStatusCode() == response.getStatus()) { // 404 throw new Exception("Invalid call to winery"); } if (Status.OK.getStatusCode() == response.getStatus()) { // 200 String json = response.readEntity(String.class); return this.parseServicetemplateJsonToList(json); } throw new Exception("Error connecting to winery"); } private List<Servicetemplate> parseServicetemplateJsonToList(String json) { JSONArray jsonArray; List<Servicetemplate> result = new ArrayList<Servicetemplate>(); try { jsonArray = new JSONArray(json); for (int i = 0; i < jsonArray.length(); i++) { String tmpId = jsonArray.getJSONObject(i).getString("id"); String tmpNamespace = jsonArray.getJSONObject(i).getString("namespace"); String tmpName = jsonArray.getJSONObject(i).getString("name"); result.add(new Servicetemplate(tmpId, tmpNamespace, tmpName)); } } catch (JSONException e) { LOGGER.error(e); } return result; } private List<String> parseErrorsJson(String json) { JSONArray jsonArray; List<String> result = new ArrayList<String>(); try { jsonArray = new JSONArray(json); for (int i = 0; i < jsonArray.length(); i++) { result.add(jsonArray.getString(i)); } } catch (JSONException e) { LOGGER.error(e); } return result; } }