From 3292d99bcb1f7a841cd7ca327448c8f15d024a36 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Thu, 24 May 2018 12:05:34 +0530 Subject: [PATCH] veeam api client: xml parsing+objects for veeam backups and jobs Signed-off-by: Rohit Yadav --- plugins/backup/veeam/pom.xml | 32 +++++-- .../cloudstack/backup/veeam/VeeamBackup.java | 62 +++++++++++--- .../backup/veeam/VeeamBackupPolicy.java | 66 +++++++++++++++ .../cloudstack/backup/veeam/VeeamClient.java | 38 +++++---- .../cloudstack/backup/veeam/VeeamObject.java | 2 + .../backup/veeam/api/EntityReferences.java | 39 +++++++++ .../cloudstack/backup/veeam/api/Link.java | 69 +++++++++++++++ .../cloudstack/backup/veeam/api/Ref.java | 84 +++++++++++++++++++ .../veeam/{ => api}/VeeamObjectType.java | 9 +- .../backup/veeam/VeeamClientTest.java | 9 +- 10 files changed, 369 insertions(+), 41 deletions(-) create mode 100644 plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamBackupPolicy.java create mode 100644 plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/EntityReferences.java create mode 100644 plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/Link.java create mode 100644 plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/Ref.java rename plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/{ => api}/VeeamObjectType.java (89%) diff --git a/plugins/backup/veeam/pom.xml b/plugins/backup/veeam/pom.xml index b05b6f64625..4cb1f72effd 100644 --- a/plugins/backup/veeam/pom.xml +++ b/plugins/backup/veeam/pom.xml @@ -17,13 +17,27 @@ under the License. --> - 4.0.0 - cloud-plugin-backup-veeam - Apache CloudStack Plugin - Veeam Backup and Recovery Plugin - - cloudstack-plugins - org.apache.cloudstack - 4.12.0.0-SNAPSHOT - ../../pom.xml - + 4.0.0 + cloud-plugin-backup-veeam + Apache CloudStack Plugin - Veeam Backup and Recovery Plugin + + cloudstack-plugins + org.apache.cloudstack + 4.12.0.0-SNAPSHOT + ../../pom.xml + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${cs.jackson.version} + + + org.apache.commons + commons-lang3 + ${cs.commons-lang3.version} + + + diff --git a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamBackup.java b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamBackup.java index bec49b06b24..02fea9906d3 100644 --- a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamBackup.java +++ b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamBackup.java @@ -17,18 +17,29 @@ package org.apache.cloudstack.backup.veeam; +import java.util.Date; import java.util.List; -public class VeeamBackup implements VeeamObject { +import org.apache.cloudstack.backup.Backup; - String uuid; - String name; - String href; - List links; +public class VeeamBackup implements Backup { + + private String name; + private String uid; + + public VeeamBackup(String name, String uid) { + this.name = name; + this.uid = uid; + } @Override - public String getUuid() { - return uuid; + public Long getAccountId() { + return null; + } + + @Override + public Long getUserId() { + return null; } @Override @@ -37,17 +48,42 @@ public class VeeamBackup implements VeeamObject { } @Override - public String getHref() { - return href; + public String getDescription() { + return "Veeam Backup"; } @Override - public VeeamObjectType getType() { - return VeeamObjectType.Backup; + public Long getParentId() { + return null; } @Override - public List getLinks() { - return links; + public Long getVMId() { + return null; + } + + @Override + public List getVolumeIds() { + return null; + } + + @Override + public Status getStatus() { + return null; + } + + @Override + public Date getStartTime() { + return null; + } + + @Override + public String getUuid() { + return uid; + } + + @Override + public long getId() { + return -1; } } diff --git a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamBackupPolicy.java b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamBackupPolicy.java new file mode 100644 index 00000000000..bd29add689a --- /dev/null +++ b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamBackupPolicy.java @@ -0,0 +1,66 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +package org.apache.cloudstack.backup.veeam; + +import org.apache.cloudstack.backup.BackupPolicy; + +public class VeeamBackupPolicy implements BackupPolicy { + + private String name; + private String uid; + + public VeeamBackupPolicy(String name, String uid) { + this.name = name; + this.uid = uid; + } + + @Override + public String getExternalId() { + return uid; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return "Veeam Backup Policy (Job)"; + } + + @Override + public boolean isImported() { + return false; + } + + @Override + public long getZoneId() { + return -1; + } + + @Override + public String getUuid() { + return uid; + } + + @Override + public long getId() { + return -1; + } +} diff --git a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamClient.java b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamClient.java index 17775836963..f8f22f9a2ce 100644 --- a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamClient.java +++ b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamClient.java @@ -17,7 +17,6 @@ package org.apache.cloudstack.backup.veeam; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.SocketTimeoutException; import java.net.URI; @@ -33,6 +32,10 @@ import javax.net.ssl.X509TrustManager; import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.backup.Backup; +import org.apache.cloudstack.backup.BackupPolicy; +import org.apache.cloudstack.backup.veeam.api.EntityReferences; +import org.apache.cloudstack.backup.veeam.api.Ref; import org.apache.cloudstack.utils.security.SSLUtils; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; @@ -60,6 +63,8 @@ import org.apache.log4j.Logger; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.nio.TrustAllManager; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; public class VeeamClient { private static final Logger LOG = Logger.getLogger(VeeamClient.class); @@ -162,14 +167,13 @@ public class VeeamClient { try { final HttpResponse response = get("/backups"); checkResponseOK(response); - // FIXME: parse XML to object - ByteArrayOutputStream outstream = new ByteArrayOutputStream(); - response.getEntity().writeTo(outstream); - byte [] responseBody = outstream.toByteArray(); - - System.out.println(new String(responseBody)); - LOG.debug("Response received = " + response.getEntity().getContent()); - return null; + final ObjectMapper objectMapper = new XmlMapper(); + final EntityReferences entityReferences = objectMapper.readValue(response.getEntity().getContent(), EntityReferences.class); + final List backups = new ArrayList<>(); + for (final Ref ref : entityReferences.getRefs()) { + backups.add(new VeeamBackup(ref.getName(), ref.getUid())); + } + return backups; } catch (final IOException e) { LOG.error("Failed to list Veeam backups due to:", e); checkResponseTimeOut(e); @@ -177,15 +181,19 @@ public class VeeamClient { return new ArrayList<>(); } - public List listJobs() { - LOG.debug("Trying to list Veeam jobs"); + + public List listBackupPolicies() { + LOG.debug("Trying to list Veeam jobs that are backup policies"); try { final HttpResponse response = get("/jobs"); checkResponseOK(response); - - // FIXME: parse XML to object - - return null; + final ObjectMapper objectMapper = new XmlMapper(); + final EntityReferences entityReferences = objectMapper.readValue(response.getEntity().getContent(), EntityReferences.class); + final List policies = new ArrayList<>(); + for (final Ref ref : entityReferences.getRefs()) { + policies.add(new VeeamBackupPolicy(ref.getName(), ref.getUid())); + } + return policies; } catch (final IOException e) { LOG.error("Failed to list Veeam jobs due to:", e); checkResponseTimeOut(e); diff --git a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamObject.java b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamObject.java index e0f83e23eaf..b8f368d986c 100644 --- a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamObject.java +++ b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamObject.java @@ -19,6 +19,8 @@ package org.apache.cloudstack.backup.veeam; import java.util.List; +import org.apache.cloudstack.backup.veeam.api.VeeamObjectType; + public interface VeeamObject { String getUuid(); String getName(); diff --git a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/EntityReferences.java b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/EntityReferences.java new file mode 100644 index 00000000000..928e0dae4a5 --- /dev/null +++ b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/EntityReferences.java @@ -0,0 +1,39 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +package org.apache.cloudstack.backup.veeam.api; + +import java.util.List; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +@JacksonXmlRootElement(localName = "EntityReferences") +public class EntityReferences { + @JacksonXmlProperty(localName = "Ref") + @JacksonXmlElementWrapper(localName = "Ref", useWrapping = false) + private List refs; + + public List getRefs() { + return refs; + } + + public void setRefs(List refs) { + this.refs = refs; + } +} diff --git a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/Link.java b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/Link.java new file mode 100644 index 00000000000..f45ba4fe673 --- /dev/null +++ b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/Link.java @@ -0,0 +1,69 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +package org.apache.cloudstack.backup.veeam.api; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +@JacksonXmlRootElement(localName = "Link") +public class Link { + + @JacksonXmlProperty(localName = "Name", isAttribute = true) + private String name; + + @JacksonXmlProperty(localName = "Href", isAttribute = true) + private String href; + + @JacksonXmlProperty(localName = "Type", isAttribute = true) + private VeeamObjectType type; + + @JacksonXmlProperty(localName = "Rel", isAttribute = true) + private String rel; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHref() { + return href; + } + + public void setHref(String href) { + this.href = href; + } + + public VeeamObjectType getType() { + return type; + } + + public void setType(String type) { + this.type = VeeamObjectType.valueOf(type); + } + + public String getRel() { + return rel; + } + + public void setRel(String rel) { + this.rel = rel; + } +} diff --git a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/Ref.java b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/Ref.java new file mode 100644 index 00000000000..b3b8d0b3286 --- /dev/null +++ b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/Ref.java @@ -0,0 +1,84 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +package org.apache.cloudstack.backup.veeam.api; + +import java.util.List; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +@JacksonXmlRootElement(localName = "Ref") +public class Ref { + @JacksonXmlProperty(localName = "UID", isAttribute = true) + private String uid; + + @JacksonXmlProperty(localName = "Name", isAttribute = true) + private String name; + + @JacksonXmlProperty(localName = "Href", isAttribute = true) + private String href; + + @JacksonXmlProperty(localName = "Type", isAttribute = true) + private VeeamObjectType type; + + @JacksonXmlProperty(localName = "Link") + @JacksonXmlElementWrapper(localName = "Links") + private List link; + + public List getLink() { + return link; + } + + public void setLink(List link) { + this.link = link; + } + + public String getUid() { + String[] fields = uid.split(":"); + return fields[fields.length - 1]; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHref() { + return href; + } + + public void setHref(String href) { + this.href = href; + } + + public VeeamObjectType getType() { + return type; + } + + public void setType(String type) { + this.type = VeeamObjectType.valueOf(type); + } +} diff --git a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamObjectType.java b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/VeeamObjectType.java similarity index 89% rename from plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamObjectType.java rename to plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/VeeamObjectType.java index c8b3c2f8013..36ebce2646e 100644 --- a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamObjectType.java +++ b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/api/VeeamObjectType.java @@ -15,13 +15,18 @@ // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.backup.veeam; +package org.apache.cloudstack.backup.veeam.api; public enum VeeamObjectType { + Job, + JobReference, + Backup, BackupReference, + BackupJobSessionReferenceList, BackupServerReference, - RestorePointReferenceList, BackupFileReferenceList, + + RestorePointReferenceList, RepositoryReference, } diff --git a/plugins/backup/veeam/src/test/java/org/apache/cloudstack/backup/veeam/VeeamClientTest.java b/plugins/backup/veeam/src/test/java/org/apache/cloudstack/backup/veeam/VeeamClientTest.java index d9583d71689..a00077c61f3 100644 --- a/plugins/backup/veeam/src/test/java/org/apache/cloudstack/backup/veeam/VeeamClientTest.java +++ b/plugins/backup/veeam/src/test/java/org/apache/cloudstack/backup/veeam/VeeamClientTest.java @@ -26,11 +26,16 @@ public class VeeamClientTest { @Before public void setUp() throws Exception { - client = new VeeamClient("http://10.2.2.89:9399/api/", "administrator", "P@ssword123", true, 300); + client = new VeeamClient("http://10.2.2.89:9399/api/", "administrator", "P@ssword123", true, 60); } @Test - public void testBasicAuth() { + public void testBackups() { client.listAllBackups(); } + + @Test + public void testPolicies() { + client.listBackupPolicies(); + } } \ No newline at end of file