Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

Commit

Permalink
#143: Refactor ShieldRestClient
Browse files Browse the repository at this point in the history
  • Loading branch information
ampersand8 committed Sep 5, 2018
1 parent a8140a4 commit 0340d0a
Show file tree
Hide file tree
Showing 11 changed files with 391 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package com.swisscom.cloud.sb.broker.backup.shield
import com.swisscom.cloud.sb.broker.backup.BackupPersistenceService
import com.swisscom.cloud.sb.broker.async.job.JobStatus
import com.swisscom.cloud.sb.broker.backup.shield.dto.*
import com.swisscom.cloud.sb.broker.backup.shield.restClient.ShieldRestClient
import com.swisscom.cloud.sb.broker.backup.shield.restClient.ShieldRestClientFactory
import com.swisscom.cloud.sb.broker.model.Backup
import com.swisscom.cloud.sb.broker.model.ServiceDetail
import com.swisscom.cloud.sb.broker.util.RestTemplateBuilder
Expand Down Expand Up @@ -162,16 +164,12 @@ class ShieldClient {
if (retention == null) {
throw new RuntimeException("Retention ${shieldServiceConfig.retentionName} that is configured does not exist on shield")
}
String schedule = shieldServiceConfig.scheduleName
if (buildClient().getAPIVersion() == 1) {
ScheduleDto scheduleDto = buildClient().getScheduleByName(shieldServiceConfig.scheduleName)
if (scheduleDto == null) {
throw new RuntimeException("Schedule ${shieldServiceConfig.scheduleName} that is configured does not exist on shield")
}
schedule = scheduleDto.uuid
ScheduleDto scheduleDto = buildClient().getScheduleByName(shieldServiceConfig.scheduleName)
if (scheduleDto == null) {
throw new RuntimeException("Schedule ${shieldServiceConfig.scheduleName} that is configured does not exist on shield")
}

createOrUpdateJob(jobName, targetUuid, store.uuid, retention.uuid, schedule, paused)
createOrUpdateJob(jobName, targetUuid, store.uuid, retention.uuid, scheduleDto.uuid, paused)
}

private String createOrUpdateTarget(ShieldTarget target, String targetName, String agent) {
Expand All @@ -192,6 +190,6 @@ class ShieldClient {
}

private ShieldRestClient buildClient() {
shieldRestClientFactory.build(restTemplateBuilder.withSSLValidationDisabled().build(), shieldConfig)
shieldRestClientFactory.build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
package com.swisscom.cloud.sb.broker.backup.shield

import com.swisscom.cloud.sb.broker.config.Config
import groovy.transform.CompileStatic
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Configuration

@CompileStatic
@Configuration
@ConfigurationProperties(prefix = "com.swisscom.cloud.sb.broker.shield")
class ShieldConfig implements Config {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2018 Swisscom (Switzerland) Ltd.
*
* 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.
*/

package com.swisscom.cloud.sb.broker.backup.shield.restClient

import com.swisscom.cloud.sb.broker.backup.shield.ShieldTarget
import com.swisscom.cloud.sb.broker.backup.shield.dto.*

interface ShieldRestClient {
Object getStatus()

boolean matchVersion()

StoreDto getStoreByName(String name)

RetentionDto getRetentionByName(String name)

ScheduleDto getScheduleByName(String name)

TargetDto getTargetByName(String name)

String createTarget(String targetName, ShieldTarget target, String agent)

String updateTarget(TargetDto existingTarget, ShieldTarget target, String agent)

void deleteTarget(String uuid)

JobDto getJobByName(String name)

JobDto getJobByUuid(String uuid)

String createJob(String jobName,
String targetUuid,
String storeUuid,
String retentionUuid,
String scheduleUuid,
boolean paused)

String updateJob(JobDto existingJob,
String targetUuid,
String storeUuid,
String retentionUuid,
String scheduleUuid,
boolean paused)

String runJob(String uuid)

void deleteJob(String uuid)

TaskDto getTaskByUuid(String uuid)

void deleteTaskByUuid(String uuid)

ArchiveDto getArchiveByUuid(String uuid)

String restoreArchive(String uuid)

void deleteArchive(String uuid)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,26 @@
* specific language governing permissions and limitations under the License.
*/

package com.swisscom.cloud.sb.broker.backup.shield
package com.swisscom.cloud.sb.broker.backup.shield.restClient

import groovy.transform.CompileStatic
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import org.springframework.web.client.RestTemplate

@Component
@CompileStatic
class ShieldRestClientFactory {
ShieldRestClient build(RestTemplate restTemplate, ShieldConfig shieldConfig) {
restTemplate.setErrorHandler(new ShieldRestResponseErrorHandler())
new ShieldRestClient(restTemplate, shieldConfig)

private List<ShieldRestClient> shieldRestClients

@Autowired
ShieldRestClientFactory(List<ShieldRestClient> shieldRestClients) {
this.shieldRestClients = shieldRestClients
}

ShieldRestClient build() {
for (ShieldRestClient shieldRestClient in shieldRestClients) {
if (shieldRestClient.matchVersion()) return shieldRestClient
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,55 +13,28 @@
* specific language governing permissions and limitations under the License.
*/

package com.swisscom.cloud.sb.broker.backup.shield
package com.swisscom.cloud.sb.broker.backup.shield.restClient


import com.swisscom.cloud.sb.broker.backup.shield.ShieldConfig
import com.swisscom.cloud.sb.broker.backup.shield.ShieldTarget
import com.swisscom.cloud.sb.broker.backup.shield.dto.*
import com.swisscom.cloud.sb.broker.util.GsonFactory
import groovy.json.JsonSlurper
import groovy.util.logging.Slf4j
import org.springframework.http.*
import org.springframework.web.client.HttpStatusCodeException
import org.springframework.http.HttpEntity
import org.springframework.http.HttpMethod
import org.springframework.web.client.RestTemplate

@Slf4j
class ShieldRestClient {
public static final String HEADER_API_KEY = 'X-Shield-Token'
public static final String HEADER_API_SESSION = 'X-Shield-Session'

private ShieldConfig config
private RestTemplate restTemplate
private int apiVersion = 1
abstract class ShieldRestClientImpl {
protected ShieldConfig config
protected RestTemplate restTemplate

ShieldRestClient(RestTemplate restTemplate, ShieldConfig shieldConfig) {
ShieldRestClientImpl(ShieldConfig shieldConfig, RestTemplate restTemplate) {
this.restTemplate = restTemplate
this.restTemplate.setErrorHandler(new ShieldRestResponseErrorHandler())
this.config = shieldConfig
this.apiVersion = getAPIVersion()
}

int getAPIVersion() {
try {
this.apiVersion = 1
def response = restTemplate.exchange(statusUrl(), HttpMethod.GET, configureRequestEntity(), String.class)
String version = new JsonSlurper().parseText(response.body).version
if (version != null && version[0..0].toInteger() == 1) return 1
else {
this.apiVersion = 2
response = restTemplate.exchange(infoUrl(), HttpMethod.GET, configureRequestEntity(), String.class)
if (new JsonSlurper().parseText(response.body).api == 2) return 2
}
} catch (HttpStatusCodeException e) {
if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
this.apiVersion = 2
def response = restTemplate.exchange(infoUrl(), HttpMethod.GET, configureRequestEntity(), String.class)
if (new JsonSlurper().parseText(response.body).api == 2) return 2
throw e
}
}
}

String getTenantUuidByName(String name) {
def response = restTemplate.exchange(tenantsUrl() + "?limit=1&name=${name}", HttpMethod.GET, configureRequestEntity(), String.class)
return new JsonSlurper().parseText(response.body)[0].uuid
}

Object getStatus() {
Expand Down Expand Up @@ -170,40 +143,26 @@ class ShieldRestClient {
String retentionUuid,
String scheduleUuid,
boolean paused = true) {
def body = [name : jobName,
target : targetUuid,
store : storeUuid,
retention: retentionUuid,
schedule : scheduleUuid,
paused : paused]

if (apiVersion == 2) {
body = replaceRetentionWithPolicy(body, retentionUuid)
}
def body = getCreateJobBody(jobName, targetUuid, storeUuid, retentionUuid, scheduleUuid, paused)
def response = restTemplate.exchange(jobsUrl(), HttpMethod.POST, configureRequestEntity(body), String.class)
new JsonSlurper().parseText(response.body).uuid
}

abstract Map<String, ?> getCreateJobBody(String jobName, String targetUuid, String storeUuid, String retentionUuid, String scheduleUuid, boolean paused)

String updateJob(JobDto existingJob,
String targetUuid,
String storeUuid,
String retentionUuid,
String scheduleUuid,
boolean paused = true) {
def body = [name : existingJob.name,
summary : existingJob.summary,
target : targetUuid,
store : storeUuid,
retention: retentionUuid,
schedule : scheduleUuid,
paused : paused]
if (apiVersion == 2) {
body = replaceRetentionWithPolicy(body, retentionUuid)
}
def body = getUpdateJobBody(existingJob, targetUuid, storeUuid, retentionUuid, scheduleUuid, paused)
restTemplate.exchange(jobUrl(existingJob.uuid), HttpMethod.PUT, configureRequestEntity(body), (Class) null)
existingJob.uuid
}

abstract Map<String, ?> getUpdateJobBody(JobDto existingJob, String targetUuid, String storeUuid, String retentionUuid, String scheduleUuid, boolean paused = true)

String runJob(String uuid) {
def response = restTemplate.exchange(jobUrl(uuid) + "/run", HttpMethod.POST, configureRequestEntity(), String.class)
new JsonSlurper().parseText(response.body).task_uuid
Expand Down Expand Up @@ -241,65 +200,49 @@ class ShieldRestClient {
restTemplate.exchange(archiveUrl(uuid), HttpMethod.DELETE, configureRequestEntity(), String.class)
}

private <T> List<T> getResources(String endpoint, final Class<T[]> clazz) {
protected <T> List<T> getResources(String endpoint, final Class<T[]> clazz) {
def response = restTemplate.exchange(endpoint, HttpMethod.GET, configureRequestEntity(), String.class)
final T[] jsonToObject = GsonFactory.withISO8601Datetime().fromJson(response.body.toString(), clazz)
return Arrays.asList(jsonToObject)
}


private <T> HttpEntity<T> configureRequestEntity(T t) {
HttpHeaders headers = new HttpHeaders()
headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE))
apiVersion == 2 ? headers.add(HEADER_API_SESSION, getSession()) : headers.add(HEADER_API_KEY, config.apiKey)
HttpEntity<T> entity = t ? new HttpEntity<T>(t, headers) : new HttpEntity<T>(headers)
return entity
}

protected String getSession() {
HttpHeaders headers = new HttpHeaders()
headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE))
def body = [username: config.username,
password: config.password]
HttpEntity<Map<String,String>> request = new HttpEntity<Map<String,String>>(body, headers)
ResponseEntity<String> response = restTemplate.exchange(loginUrl(), HttpMethod.POST, request, String.class)
return response.getHeaders().getValuesAsList(HEADER_API_SESSION)[0]
}
abstract protected <T> HttpEntity<T> configureRequestEntity(T t)

protected String storesUrl() {
"${tenantBasedUrl()}/stores"
"${baseUrl()}/stores"
}

protected String retentionsUrl() {
apiVersion == 2 ? "${tenantBasedUrl()}/policies" : "${tenantBasedUrl()}/retention"
"${baseUrl()}/retention"
}

protected String schedulesUrl() {
"${tenantBasedUrl()}/schedules"
"${baseUrl()}/schedules"
}

protected String taskUrl(String uuid) {
"${tenantBasedUrl()}/task/${uuid}"
"${baseUrl()}/task/${uuid}"
}

protected String archiveUrl(String uuid) {
"${tenantBasedUrl()}/archive/${uuid}"
"${baseUrl()}/archive/${uuid}"
}

protected String targetsUrl() {
"${tenantBasedUrl()}/targets"
"${baseUrl()}/targets"
}

protected String targetUrl(String uuid) {
"${tenantBasedUrl()}/target/${uuid}"
"${baseUrl()}/target/${uuid}"
}

protected String jobsUrl() {
"${tenantBasedUrl()}/jobs"
"${baseUrl()}/jobs"
}

protected String jobUrl(String uuid) {
"${tenantBasedUrl()}/job/${uuid}"
"${baseUrl()}/job/${uuid}"
}

protected String statusUrl() {
Expand All @@ -318,22 +261,6 @@ class ShieldRestClient {
"${baseUrl()}/auth/login"
}

private String tenantBasedUrl() {
apiVersion == 2 ? "${baseUrl()}/tenants/${getTenantUuidByName(config.defaultTenantName)}" : baseUrl()
}
abstract protected String baseUrl()

private String baseUrl() {
"${config.baseUrl}/v${apiVersion}"
}

private Map<String,String> replaceRetentionWithPolicy(Map<?, ?> body, String retention) {
def iterator = body.entrySet().iterator()
while (iterator.hasNext()) {
if (iterator.next().key == "retention") {
iterator.remove()
}
}
body.put("policy", retention)
return body
}
}
Loading

0 comments on commit 0340d0a

Please sign in to comment.