package gov.samhsa.acs.polrep.client; import gov.samhsa.acs.polrep.client.dto.PolicyContainerDto; import gov.samhsa.acs.polrep.client.dto.PolicyContentContainerDto; import gov.samhsa.acs.polrep.client.dto.PolicyContentDto; import gov.samhsa.acs.polrep.client.dto.PolicyDto; import gov.samhsa.acs.polrep.client.dto.PolicyMetadataContainerDto; import gov.samhsa.acs.polrep.client.dto.PolicyMetadataDto; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URIBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.util.Assert; import org.springframework.web.client.HttpStatusCodeException; import org.springframework.web.client.RestTemplate; public class PolRepRestClient { public static final String DEFAULT_ENCODING = "UTF-8"; public static final String DEFAULT_WILDCARD = "*"; private static final String PARAM_NAME_WILDCARD = "wildcard"; private static final String PARAM_NAME_FORCE = "force"; private static final String PARAM_NAME_POLICY_SET_ID = "policySetId"; private static final String PARAM_NAME_POLICY_COMBINING_ALG_ID = "policyCombiningAlgId"; private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final String scheme; private final String host; private final int port; private final String context; private final String version; private HttpHeaders httpHeaders; private RestTemplate restTemplate; public PolRepRestClient(String scheme, String host, int port, String context, String version) { super(); this.scheme = scheme; this.host = host; this.port = port; this.context = context; this.version = version; init(); } public PolicyMetadataContainerDto addPolicies( PolicyContentContainerDto addPolicyRequestContainerDto, boolean force) { final String apiPath = Paths.POLICIES.getPath(); final List<NameValuePair> parameters = NVPBuilder.withParam( PARAM_NAME_FORCE, Boolean.toString(force)).build(); return post(apiPath, parameters, httpEntity(addPolicyRequestContainerDto), PolicyMetadataContainerDto.class); } public void deletePolicy(String policyId) { final String apiPath = Paths.POLICIES_WITH_PARAM.getPath(policyId); delete(apiPath); } public PolicyContainerDto getPolicies(String policyId, String wildcard) { final String apiPath = Paths.POLICIES_WITH_PARAM.getPath(policyId); final List<NameValuePair> parameters = wildcard != null ? NVPBuilder .withParam(PARAM_NAME_WILDCARD, wildcard).build() : null; return get(apiPath, parameters, PolicyContainerDto.class); } public PolicyDto getPoliciesCombinedAsPolicySet(String policyId, String wildcard, String policySetId, PolicyCombiningAlgIds policyCombiningAlgId) { final String apiPath = Paths.POLICIES_COMBINED_WITH_PARAM .getPath(policyId); final NVPBuilder nvpBuilder = NVPBuilder.withParam( PARAM_NAME_POLICY_SET_ID, policySetId).and( PARAM_NAME_POLICY_COMBINING_ALG_ID, policyCombiningAlgId.getUrn()); if (wildcard != null) { nvpBuilder.and(PARAM_NAME_WILDCARD, wildcard); } final List<NameValuePair> parameters = nvpBuilder.build(); return get(apiPath, parameters, PolicyDto.class); } public PolicyDto getPolicy(String policyId) { return getPolicies(policyId, null).getPolicies().get(0); } @SuppressWarnings("unchecked") public Map<String, String> getPolicyCombiningAlgIds() { final String apiPath = Paths.POLICY_COMBINING_ALG_IDS.getPath(); return get(apiPath, null, Map.class); } public PolicyMetadataDto updatePolicy( PolicyContentDto updatePolicyRequestDto, String policyId) { final String apiPath = Paths.POLICIES_WITH_PARAM.getPath(policyId); return put(apiPath, httpEntity(updatePolicyRequestDto), PolicyMetadataDto.class); } private URI buildURI(final String apiPath) { return buildURI(apiPath, null); } private URI buildURI(final String apiPath, final List<NameValuePair> parameters) { URI url; final String path = getPath(apiPath); final URIBuilder builder = newURIBuilder(); builder.setPath(path); if (parameters != null && parameters.size() > 0) { builder.addParameters(parameters); } try { url = builder.build(); } catch (final URISyntaxException e) { throw new RuntimeException(e); } return url; } private void delete(String apiPath) { final URI url = buildURI(apiPath); try { restTemplate.exchange(url, HttpMethod.DELETE, httpEntity(), Object.class); } catch (final HttpStatusCodeException e) { logger.error(e.getMessage(), e); logger.error(e.getResponseBodyAsString()); throw e; } } private <R> R get(String apiPath, List<NameValuePair> parameters, Class<R> responseType) { final URI url = buildURI(apiPath, parameters); try { return restTemplate.exchange(url, HttpMethod.GET, httpEntity(), responseType).getBody(); } catch (final HttpStatusCodeException e) { logger.error(e.getMessage(), e); logger.error(e.getResponseBodyAsString()); throw e; } } private String getPath(String apiPath) { final StringBuilder pathBuilder = new StringBuilder(); if (!this.context.startsWith("/")) { pathBuilder.append("/"); } pathBuilder.append(this.context); pathBuilder.append("/rest/"); pathBuilder.append(this.version); pathBuilder.append(apiPath); return pathBuilder.toString(); } @SuppressWarnings({ "unchecked", "rawtypes" }) private HttpEntity httpEntity() { Assert.notNull(this.httpHeaders, "HttpHeaders is not initialized!"); return new HttpEntity(this.httpHeaders); } @SuppressWarnings({ "unchecked", "rawtypes" }) private <T> HttpEntity<T> httpEntity(T request) { Assert.notNull(this.httpHeaders, "HttpHeaders is not initialized!"); return new HttpEntity(request, this.httpHeaders); } private void init() { Assert.hasText(this.scheme, "Scheme is not passed!"); Assert.hasText(this.host, "Host is not passed!"); Assert.isTrue(this.port > 0, "Port is not passed!"); Assert.hasText(this.context, "Context is not passed!"); Assert.hasText(this.version, "Version is not passed!"); initRestTemplate(); initHttpHeaders(); } private void initHttpHeaders() { this.httpHeaders = new HttpHeaders(); this.httpHeaders.setContentType(MediaType.APPLICATION_JSON); this.httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); this.httpHeaders.setAcceptCharset(Arrays.asList(Charset .forName(DEFAULT_ENCODING))); } private void initRestTemplate() { this.restTemplate = new RestTemplate(); final List<HttpMessageConverter<?>> messageConverters = restTemplate .getMessageConverters(); // Create a list for the message converters final List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>( messageConverters); final MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); // Add the Jackson Message converter converters.add(jsonConverter); this.restTemplate.setMessageConverters(converters); } private URIBuilder newURIBuilder() { final URIBuilder builder = new URIBuilder(); builder.setScheme(this.scheme); builder.setHost(this.host); builder.setPort(this.port); return builder; } private <R> R post(String apiPath, List<NameValuePair> parameters, HttpEntity<Object> request, Class<R> responseType) { final URI url = buildURI(apiPath, parameters); try { return restTemplate.postForObject(url, request, responseType); } catch (final HttpStatusCodeException e) { logger.error(e.getMessage(), e); logger.error(e.getResponseBodyAsString()); throw e; } } private <R> R put(String apiPath, HttpEntity<Object> request, Class<R> responseType) { final URI url = buildURI(apiPath); try { return restTemplate.exchange(url, HttpMethod.PUT, request, responseType).getBody(); } catch (final HttpStatusCodeException e) { logger.error(e.getMessage(), e); logger.error(e.getResponseBodyAsString()); throw e; } } }