/*- * ============LICENSE_START======================================================= * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= */ package com.woorea.openstack.glance; import com.woorea.openstack.base.client.Entity; import com.woorea.openstack.base.client.HttpMethod; import com.woorea.openstack.base.client.OpenStackClient; import com.woorea.openstack.base.client.OpenStackRequest; import com.woorea.openstack.base.client.OpenStackResponse; import com.woorea.openstack.glance.model.Image; import com.woorea.openstack.glance.model.ImageDownload; import com.woorea.openstack.glance.model.ImageMember; import com.woorea.openstack.glance.model.ImageMembers; import com.woorea.openstack.glance.model.ImageUpload; import com.woorea.openstack.glance.model.Images; import java.util.Calendar; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.codehaus.jackson.annotate.JsonProperty; public class ImagesResource { private static final String IMAGES = "/images/"; private static final String MEMBERS = "/members"; private final OpenStackClient client; public ImagesResource(OpenStackClient client) { this.client = client; } public List list(boolean detail) { return new List(detail); } public Create create(Image image) { return new Create(image); } public Show show(String id) { return new Show(id); } public Update update(String id, Image image) { return new Update(id, image); } public Delete delete(String id) { return new Delete(id); } public Upload upload(ImageUpload image) { return new Upload(image); } public Upload upload(String id, ImageUpload image) { return new Upload(id, image); } public Download download(String id) { return new Download(id); } public ListMembers listMembers(String id) { return new ListMembers(id); } public ReplaceMembers replaceMembers(String id, Collection members) { return new ReplaceMembers(id, members); } public AddMember addMember(String id, String tenantId) { return new AddMember(id, tenantId); } public AddMember removeMember(String id, String tenantId) { return new AddMember(id, tenantId); } public class List extends OpenStackRequest { public List(boolean detail) { super(client, HttpMethod.GET, detail ? IMAGES + "detail" : "images", null, Images.class); } } public class Create extends OpenStackRequest { public Create(Image image) { super(client, HttpMethod.POST, "/images", null, Image.class); for (Map.Entry entry : compose(image).entrySet()) { header(entry.getKey(), entry.getValue()); } } } public class Update extends OpenStackRequest { public Update(String id, Image image) { super(client, HttpMethod.PUT, new StringBuilder(IMAGES).append(id).toString(), Entity.json(image), Image.class); } } public class Delete extends OpenStackRequest { public Delete(String id) { super(client, HttpMethod.DELETE, new StringBuilder(IMAGES).append(id).toString(), null, Void.class); } } public class Show extends OpenStackRequest { public Show(String id) { super(client, HttpMethod.HEAD, new StringBuilder(IMAGES).append(id).toString(), null, Image.class); } @Override public Image execute() { // custom parsing here return parse(client.request(this).headers()); } } public class Upload extends OpenStackRequest { public Upload(String id, ImageUpload imageUpload) { super(client, HttpMethod.PUT, new StringBuilder(IMAGES).append(id).toString(), Entity.stream(imageUpload.getInputStream()), Image.class); } public Upload(ImageUpload imageUpload) { super(client, HttpMethod.POST, "/images", Entity.stream(imageUpload.getInputStream()), Image.class); for (Map.Entry entry : compose(imageUpload.getImage()).entrySet()) { header(entry.getKey(), entry.getValue()); } //file,s3,swift header("x-image-meta-store", imageUpload.getStore()); } } public class Download extends OpenStackRequest { public Download(String id) { super(client, HttpMethod.GET, new StringBuilder(IMAGES).append(id).toString(), null, ImageDownload.class); header("Accept", "application/octet-stream"); } @Override public ImageDownload execute() { // custom parsing here OpenStackResponse response = client.request(this); ImageDownload imageDownload = new ImageDownload(); imageDownload.setImage(parse(response.headers())); imageDownload.setInputStream(response.getInputStream()); return imageDownload; } } public class ListMembers extends OpenStackRequest { public ListMembers(String id) { super(client, HttpMethod.GET, new StringBuilder(IMAGES).append(id).append(MEMBERS).toString(), null, ImageMembers.class); } } public class ReplaceMembers extends OpenStackRequest { public ReplaceMembers(String id, Collection members) { super(client, HttpMethod.PUT, new StringBuilder(IMAGES).append(id).append(MEMBERS).toString(), Entity.json(new Memberships(members)), Void.class); } } public class AddMember extends OpenStackRequest { public AddMember(String id, String tenantId) { super(client, HttpMethod.PUT, new StringBuilder(IMAGES).append(id).append(MEMBERS).append(tenantId).toString(), null, ImageMember.class); } } public class RemoveMember extends OpenStackRequest { public RemoveMember(String id, String tenantId) { super(client, HttpMethod.DELETE, new StringBuilder(IMAGES).append(id).append("/members/").append(tenantId).toString(), null, Void.class); } } public static Map compose(Image image) { Map headers = new HashMap<>(); headers.put("X-Image-Meta-Name", image.getName()); headers.put("X-Image-Meta-Disk_format", image.getDiskFormat()); headers.put("X-Image-Meta-Container_format", image.getContainerFormat()); headers.put("X-Image-Meta-Id", image.getId()); headers.put("X-Image-Meta-Size", image.getSize() != null ? image.getSize().toString() : null); headers.put("X-Image-Meta-Checksum", image.getChecksum()); headers.put("X-Image-Meta-Is_public", String.valueOf(image.isPublic())); headers.put("X-Image-Meta-Owner", image.getOwner()); for (String key : image.getProperties().keySet()) { image.getProperties().put("x-image-meta-property-" + key, image.getProperties().get(key)); } return headers; } public static Image parse(Map headers) { Image image = new Image(); image.setId(headers.get("X-Image-Meta-Id")); image.setUri(headers.get("Location")); image.setName(headers.get("X-Image-Meta-Name")); image.setDiskFormat(headers.get("X-Image-Meta-Disk_format")); image.setContainerFormat(headers.get("X-Image-Meta-Container_format")); image.setSize(asLong(headers.get("X-Image-Meta-Size"))); image.setChecksum(headers.get("X-Image-Meta-Checksum")); image.setCreatedAt(asCalendar(headers.get("X-Image-Meta-Created_at"))); image.setUpdatedAt(asCalendar(headers.get("X-Image-Meta-Updated_at"))); image.setDeletedAt(asCalendar(headers.get("X-Image-Meta-Deleted_at"))); image.setDeleted(asBoolean(headers.get("X-Image-Meta-Deleted"))); image.setStatus(headers.get("X-Image-Meta-Status")); image.setProtected(asBoolean(headers.get("X-Image-Meta-Protected"))); image.setPublic(asBoolean(headers.get("X-Image-Meta-Is_public"))); image.setMinRam(asInteger(headers.get("X-Image-Meta-Min_ram"))); image.setMinDisk(asInteger(headers.get("X-Image-Meta-Min_disk"))); image.setOwner(headers.get("X-Image-Meta-Owner")); for (Map.Entry entry : headers.entrySet()) { String key = entry.getKey(); if (key.startsWith("x-image-meta-property-")) { image.getProperties().put(key.substring(22), entry.getValue()); } } return image; } private static Calendar asCalendar(String calendarString) { return Calendar.getInstance(); } private static Integer asInteger(String integerString) { if (integerString != null) { return Integer.parseInt(integerString); } return 0; } private static Boolean asBoolean(String booleanString) { if (booleanString != null) { return Boolean.parseBoolean(booleanString); } return Boolean.FALSE; } private static Long asLong(String longString) { if (longString != null) { return Long.parseLong(longString); } return 0L; } public static class Memberships { @JsonProperty("memberships") private Collection imageMembers; public Memberships(Collection imageMembers) { this.imageMembers = imageMembers; } } }