com.sastix.cms.client.impl.CmsClient.java Source code

Java tutorial

Introduction

Here is the source code for com.sastix.cms.client.impl.CmsClient.java

Source

/*
 * Copyright(c) 2016 the original author or authors.
 *
 * 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.sastix.cms.client.impl;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.hazelcast.core.HazelcastInstance;
import com.sastix.cms.client.CacheClient;
import com.sastix.cms.client.ContentClient;
import com.sastix.cms.client.LockClient;
import com.sastix.cms.common.Constants;
import com.sastix.cms.common.cache.CacheDTO;
import com.sastix.cms.common.cache.QueryCacheDTO;
import com.sastix.cms.common.cache.RemoveCacheDTO;
import com.sastix.cms.common.cache.exceptions.CacheValidationException;
import com.sastix.cms.common.cache.exceptions.DataNotFound;
import com.sastix.cms.common.client.ApiVersionClient;
import com.sastix.cms.common.client.RetryRestTemplate;
import com.sastix.cms.common.content.CreateResourceDTO;
import com.sastix.cms.common.content.DataDTO;
import com.sastix.cms.common.content.LockedResourceDTO;
import com.sastix.cms.common.content.ResourceDTO;
import com.sastix.cms.common.content.ResourceQueryDTO;
import com.sastix.cms.common.content.RevisionDTO;
import com.sastix.cms.common.content.UpdateResourceDTO;
import com.sastix.cms.common.content.exceptions.ContentValidationException;
import com.sastix.cms.common.content.exceptions.ResourceAccessError;
import com.sastix.cms.common.content.exceptions.ResourceNotFound;
import com.sastix.cms.common.content.exceptions.ResourceNotOwned;
import com.sastix.cms.common.dataobjects.ResponseDTO;
import com.sastix.cms.common.dataobjects.VersionDTO;
import com.sastix.cms.common.lock.LockDTO;
import com.sastix.cms.common.lock.NewLockDTO;
import com.sastix.cms.common.lock.QueryLockDTO;
import com.sastix.cms.common.lock.exceptions.LockNotAllowed;
import com.sastix.cms.common.lock.exceptions.LockNotFound;
import com.sastix.cms.common.lock.exceptions.LockNotHeld;
import com.sastix.cms.common.lock.exceptions.LockValidationException;

@Service
public class CmsClient implements ContentClient, LockClient, CacheClient, BeanFactoryAware {
    private Logger LOG = (Logger) LoggerFactory.getLogger(CmsClient.class);

    @Autowired
    @Qualifier("CmsApiVersionClient")
    ApiVersionClient apiVersionClient;

    @Autowired
    @Qualifier("CmsRestTemplate")
    RetryRestTemplate retryRestTemplate;

    Optional<HazelcastInstance> hazelcastInstance;

    private String getUrlRoot() {
        StringBuffer url = new StringBuffer(apiVersionClient.getApiUrl()).append("/");
        return url.toString();
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        try {
            HazelcastInstance hz = beanFactory.getBean(HazelcastInstance.class);
            hazelcastInstance = Optional.of(hz);
            LOG.info("A local HZ instance (uid={}) can be found/used on this service.",
                    hazelcastInstance.get().getLocalEndpoint().getUuid());
        } catch (final Exception e) {
            LOG.warn("Hazelcast Instance not found on this Server");
            hazelcastInstance = Optional.empty();
        }
    }

    @Override
    public VersionDTO getApiVersion() {
        return apiVersionClient.getApiVersion();
    }

    @Override
    public LockedResourceDTO lockResource(ResourceDTO resourceDTO)
            throws ResourceNotFound, ResourceNotOwned, ResourceAccessError, ContentValidationException {
        String url = apiVersionClient.getApiUrl() + "/" + Constants.LOCK_RESOURCE_DTO;
        LOG.trace("API call: " + url);
        LOG.trace("Request: " + resourceDTO.toString());
        LockedResourceDTO lockedResourceDTO = retryRestTemplate.postForObject(url, resourceDTO,
                LockedResourceDTO.class);
        LOG.trace("Response: " + lockedResourceDTO.toString());
        return lockedResourceDTO;
    }

    @Override
    public void unlockResource(LockedResourceDTO lockedResourceDTO)
            throws ResourceNotFound, ResourceNotOwned, ContentValidationException {
        String url = apiVersionClient.getApiUrl() + "/" + Constants.UNLOCK_RESOURCE_DTO;
        LOG.trace("API call: " + url);
        LOG.trace("Request: " + lockedResourceDTO.toString());
        retryRestTemplate.postForObject(url, lockedResourceDTO, LockedResourceDTO.class);
    }

    @Override
    public LockedResourceDTO renewResourceLock(LockedResourceDTO lockedResourceDTO)
            throws ResourceNotFound, ResourceNotOwned, ContentValidationException {
        String url = apiVersionClient.getApiUrl() + "/" + Constants.RENEW_RESOURCE_DTO_LOCK;
        LOG.trace("API call: " + url);
        LOG.trace("Request: " + lockedResourceDTO.toString());
        LockedResourceDTO newLockedResourceDTO = retryRestTemplate.postForObject(url, lockedResourceDTO,
                LockedResourceDTO.class);
        LOG.trace("Response: " + newLockedResourceDTO.toString());
        return newLockedResourceDTO;
    }

    @Override
    public ResourceDTO createResource(CreateResourceDTO createResourceDTO)
            throws ResourceAccessError, ContentValidationException {
        String url = apiVersionClient.getApiUrl() + "/" + Constants.CREATE_RESOURCE;
        LOG.trace("API call: " + url);
        //LOG.trace("Request: " + createResourceDTO.toString());
        ResourceDTO resourceDTO = retryRestTemplate.postForObject(url, createResourceDTO, ResourceDTO.class);
        //LOG.trace("Response: " + resourceDTO.toString());
        return resourceDTO;
    }

    @Override
    public LockedResourceDTO updateResource(UpdateResourceDTO updateResourceDTO)
            throws ResourceNotOwned, ResourceAccessError, ContentValidationException {
        String url = apiVersionClient.getApiUrl() + "/" + Constants.UPDATE_RESOURCE;
        LOG.trace("API call: " + url);
        LOG.trace("Request: " + updateResourceDTO.toString());
        LockedResourceDTO lockedResourceDTO = retryRestTemplate.postForObject(url, updateResourceDTO,
                LockedResourceDTO.class);
        LOG.trace("Response: " + lockedResourceDTO.toString());
        return lockedResourceDTO;
    }

    @Override
    public ResourceDTO queryResource(ResourceQueryDTO resourceQueryDTO)
            throws ResourceAccessError, ResourceNotFound, ContentValidationException {
        String url = apiVersionClient.getApiUrl() + "/" + Constants.QUERY_RESOURCE;
        LOG.trace("API call: " + url);
        LOG.trace("Request: " + resourceQueryDTO.toString());
        ResourceDTO resourceDTO = retryRestTemplate.postForObject(url, resourceQueryDTO, ResourceDTO.class);
        LOG.trace("Response: {}", resourceDTO);
        return resourceDTO;
    }

    @Override
    public ResourceDTO deleteResource(LockedResourceDTO lockedResourceDTO)
            throws ResourceNotOwned, ResourceAccessError, ContentValidationException {
        String url = apiVersionClient.getApiUrl() + "/" + Constants.DELETE_RESOURCE;
        LOG.trace("API call: " + url);
        LOG.trace("Request: " + lockedResourceDTO.toString());
        ResourceDTO resourceDTO = retryRestTemplate.postForObject(url, lockedResourceDTO, ResourceDTO.class);
        LOG.trace("Response: " + resourceDTO.toString());
        return resourceDTO;
    }

    @Override
    public byte[] getData(DataDTO dataDTO) throws ResourceAccessError, ContentValidationException {
        String url = apiVersionClient.getApiUrl() + "/" + Constants.GET_DATA;
        LOG.trace("API call: " + url);
        LOG.trace("Request: " + dataDTO.toString());
        return retryRestTemplate.postForObject(url, dataDTO, byte[].class);
    }

    @Override
    public ResponseDTO getDataStream(DataDTO dataDTO)
            throws ResourceAccessError, ContentValidationException, IOException {
        return getData(dataDTO.getResourceURI());
    }

    @Override
    public ResponseDTO getData(final String uri) throws IOException {
        final String url = apiVersionClient.getApiUrl() + "/" + Constants.GET_DATA + "/" + uri;
        URLConnection urlConnection = new URL(url).openConnection();
        final Map<String, List<String>> headers = urlConnection.getHeaderFields();
        final InputStream inputStream = urlConnection.getInputStream();
        final Map<String, String> responseHeaders = new HashMap<>();
        responseHeaders.put(ResponseDTO.CONTENT_TYPE, headers.get(ResponseDTO.CONTENT_TYPE).get(0));
        return new ResponseDTO(inputStream, responseHeaders);
    }

    @Override
    public ResponseDTO getMultiPartData(final String uri, final Map<String, List<String>> reqHeaders)
            throws IOException {
        final String url = apiVersionClient.getApiUrl() + "/" + Constants.GET_MULTIPART_DATA + "/" + uri;

        final HttpHeaders headers = new HttpHeaders();
        headers.putAll(reqHeaders);

        final HttpEntity<String> entity = new HttpEntity<>("parameters", headers);

        final ResponseEntity<byte[]> responseEntity = retryRestTemplate.exchange(url, HttpMethod.GET, entity,
                byte[].class);

        final Integer httpStatus = responseEntity.getStatusCode().value();

        return new ResponseDTO(responseEntity.getBody(), responseEntity.getHeaders().toSingleValueMap(),
                httpStatus);
    }

    @Override
    public ResponseDTO getDataFromUUID(final String uuid) throws IOException {
        final String url = apiVersionClient.getApiUrl() + "/" + Constants.GET_DATA_FROM_UUID + "/" + uuid;
        URLConnection urlConnection = new URL(url).openConnection();
        final Map<String, List<String>> headers = urlConnection.getHeaderFields();
        final InputStream inputStream = urlConnection.getInputStream();
        final Map<String, String> responseHeaders = new HashMap<>();
        responseHeaders.put(ResponseDTO.CONTENT_TYPE, headers.get(ResponseDTO.CONTENT_TYPE).get(0));
        return new ResponseDTO(inputStream, responseHeaders);
    }

    @Override
    public String getParentResource(final String uuid) throws ResourceNotFound {
        String url = apiVersionClient.getApiUrl() + "/" + Constants.GET_PARENT_UUID;
        LOG.trace("API call: " + url);
        LOG.trace("Request of parent uuid of: " + uuid);
        String ret = retryRestTemplate.postForObject(url, uuid, String.class);
        LOG.trace("Response: {}", ret);
        return ret;
    }

    @Override
    public URL getDataURL(final String uri) throws IOException {
        final String url = apiVersionClient.getApiUrl() + "/" + Constants.GET_DATA + "/" + uri;
        return new URL(url);
    }

    @Override
    public void cacheResource(CacheDTO cacheDTO) throws DataNotFound, CacheValidationException {
        nullValidationChecker(cacheDTO, CacheDTO.class);
        boolean isNotValidObject = cacheDTO.getCacheKey() == null
                || (cacheDTO.getCacheBlobBinary() == null && cacheDTO.getCacheBlobURI() == null);
        if (isNotValidObject) {
            throw new CacheValidationException("CacheDTO object is missing mandatory fields");
        } else {
            StringBuffer url = new StringBuffer(getUrlRoot()).append(Constants.PUT_CACHE);
            LOG.debug("API call: " + url);
            LOG.debug("Request DTO: " + cacheDTO.toString());
            retryRestTemplate.postForObject(url.toString(), cacheDTO, CacheDTO.class);
        }
    }

    @Override
    public void removeCachedResource(RemoveCacheDTO removeCacheDTO) throws DataNotFound, CacheValidationException {
        nullValidationChecker(removeCacheDTO, RemoveCacheDTO.class);
        boolean isNotValidObject = removeCacheDTO.getCacheKey() == null;
        if (isNotValidObject) {
            throw new CacheValidationException("RemoveCacheDTO object is missing the cacheKey");
        } else {
            StringBuffer url = new StringBuffer(getUrlRoot()).append(Constants.REMOVE_CACHE);
            LOG.debug("API call: " + url);
            LOG.debug("Request DTO: " + removeCacheDTO.toString());
            retryRestTemplate.postForObject(url.toString(), removeCacheDTO, RemoveCacheDTO.class);
        }
    }

    @Override
    public CacheDTO getCachedResource(QueryCacheDTO queryCacheDTO) throws DataNotFound, CacheValidationException {
        nullValidationChecker(queryCacheDTO, QueryCacheDTO.class);
        boolean isNotValidObject = queryCacheDTO.getCacheKey() == null;
        CacheDTO cacheDTO = null;
        if (isNotValidObject) {
            throw new CacheValidationException("QueryCacheDTO object is missing the cacheKey");
        } else {
            if (hazelcastInstance.isPresent()) {
                final String cache = StringUtils.isEmpty(queryCacheDTO.getCacheRegion())
                        ? Constants.DEFAULT_CACHE_NAME
                        : queryCacheDTO.getCacheRegion();
                LOG.debug("Trying to find resource ({},{}) in local HZ instance", queryCacheDTO.getCacheKey(),
                        cache);
                if (hazelcastInstance.get().getMap(cache).containsKey(queryCacheDTO.getCacheKey())) {
                    try {
                        cacheDTO = (CacheDTO) hazelcastInstance.get().getMap(cache)
                                .get(queryCacheDTO.getCacheKey());
                        if (cacheDTO.getCacheExpirationTime().isBeforeNow()) {
                            final RemoveCacheDTO removeCacheDTO = new RemoveCacheDTO();
                            removeCacheDTO.setCacheKey(queryCacheDTO.getCacheKey());
                            removeCacheDTO.setCacheRegion(queryCacheDTO.getCacheRegion());
                            removeCachedResource(removeCacheDTO);
                        } else {
                            LOG.debug("Resource ({},{}) found in local HZ instance", queryCacheDTO.getCacheKey(),
                                    cache);
                            return cacheDTO;
                        }
                    } catch (Exception e) {
                        LOG.debug("QueryCacheDTO with key={} was not found in region={}",
                                queryCacheDTO.getCacheKey(), queryCacheDTO.getCacheRegion());
                    }
                }
            }

            StringBuffer url = new StringBuffer(getUrlRoot()).append(Constants.GET_CACHE);
            LOG.debug("API call: " + url);
            LOG.debug("Request DTO: " + queryCacheDTO.toString());

            cacheDTO = retryRestTemplate.postForObject(url.toString(), queryCacheDTO, CacheDTO.class);

            LOG.debug("Response DTO: {}", cacheDTO);

        }
        return cacheDTO;
    }

    @Override
    public void clearCache(RemoveCacheDTO removeCacheDTO) throws DataNotFound, CacheValidationException {
        nullValidationChecker(removeCacheDTO, RemoveCacheDTO.class);
        StringBuffer url = new StringBuffer(getUrlRoot()).append(Constants.CLEAR_CACHE_REGION);
        LOG.debug("API call: " + url);
        if (removeCacheDTO != null)
            LOG.debug("Request DTO: " + removeCacheDTO.toString());
        retryRestTemplate.postForObject(url.toString(), removeCacheDTO, RemoveCacheDTO.class);
    }

    @Override
    public void clearCache() {
        StringBuffer url = new StringBuffer(getUrlRoot()).append(Constants.CLEAR_CACHE_ALL);
        LOG.debug("API call: " + url);
        retryRestTemplate.postForObject(url.toString(), true, Boolean.class);
    }

    @Override
    public void clearCacheExcept(List<String> cacheRegions) {
        StringBuffer url = new StringBuffer(getUrlRoot()).append(Constants.CLEAR_CACHE_ALL_EXCEPT);
        LOG.debug("API call: " + url);
        retryRestTemplate.postForObject(url.toString(), cacheRegions, List.class);
    }

    @Override
    public String getUID(String region) {
        StringBuilder url = new StringBuilder(getUrlRoot()).append(Constants.GET_UID);
        LOG.debug("API call: " + url);
        if (StringUtils.isEmpty(region)) {
            region = Constants.UID_REGION;
        }
        final String UID = retryRestTemplate.postForObject(url.toString(), region, String.class);
        return UID;
    }

    @Override
    public String getUID() {
        StringBuilder url = new StringBuilder(getUrlRoot()).append(Constants.GET_UID);
        LOG.debug("API call: " + url);
        final String UID = retryRestTemplate.postForObject(url.toString(), Constants.UID_REGION, String.class);
        return UID;
    }

    @Override
    public LockDTO lockResource(NewLockDTO newLockDTO) throws LockNotAllowed, LockValidationException {
        nullValidationChecker(newLockDTO, NewLockDTO.class);
        StringBuilder url = new StringBuilder(getUrlRoot()).append(Constants.LOCK_RESOURCE);
        LOG.debug("API call: " + url);
        LOG.debug("NewLockDTO: " + newLockDTO.toString());
        LockDTO lockDTO = retryRestTemplate.postForObject(url.toString(), newLockDTO, LockDTO.class);
        return lockDTO;
    }

    @Override
    public void unlockResource(LockDTO lockDTO) throws LockNotHeld, LockValidationException {
        nullValidationChecker(lockDTO, LockDTO.class);
        StringBuilder url = new StringBuilder(getUrlRoot()).append(Constants.UNLOCK_RESOURCE);
        LOG.debug("API call: " + url);
        LOG.debug("LockDTO: " + lockDTO.toString());
        retryRestTemplate.postForObject(url.toString(), lockDTO, LockDTO.class);
    }

    @Override
    public LockDTO renewResourceLock(LockDTO lockDTO) throws LockNotAllowed, LockNotHeld, LockValidationException {
        nullValidationChecker(lockDTO, LockDTO.class);
        StringBuilder url = new StringBuilder(getUrlRoot()).append(Constants.RENEW_RESOURCE_LOCK);
        LOG.debug("API call: " + url);
        LOG.debug("LockDTO: " + lockDTO.toString());
        LockDTO retLockDTO = retryRestTemplate.postForObject(url.toString(), lockDTO, LockDTO.class);
        return retLockDTO;
    }

    @Override
    public LockDTO queryResourceLock(QueryLockDTO queryLockDTO) throws LockNotFound, LockValidationException {
        nullValidationChecker(queryLockDTO, QueryLockDTO.class);
        StringBuilder url = new StringBuilder(getUrlRoot()).append(Constants.QUERY_RESOURCE_LOCK);
        LOG.debug("API call: " + url);
        LOG.debug("QueryDTO: " + queryLockDTO.toString());
        LockDTO retLockDTO = retryRestTemplate.postForObject(url.toString(), queryLockDTO, LockDTO.class);
        return retLockDTO;
    }

    private void nullValidationChecker(Object obj, Class aClass) {
        if (obj == null) {
            throw new CacheValidationException(aClass + " object cannot be null!");
        }
    }

    @Override
    public List<ResourceDTO> getCurrentResources() {
        StringBuilder url = new StringBuilder(getUrlRoot()).append(Constants.GET_CURRENT_RESOURCES);
        LOG.debug("API call: " + url);
        List resourceDTOs = retryRestTemplate.getForObject(url.toString(), List.class);
        return resourceDTOs;
    }

    @Override
    public List<RevisionDTO> getResourceRevisions(String resourceUID) {
        StringBuilder url = new StringBuilder(getUrlRoot()).append(Constants.GET_RESOURCE_REVISIONS);
        LOG.debug("API call: " + url);
        LOG.debug("resourceUID: " + resourceUID);
        List revisionDTOs = retryRestTemplate.postForObject(url.toString(), resourceUID, List.class);
        return revisionDTOs;
    }
}