All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hp.octane.integrations.services.entities.EntitiesServiceImpl Maven / Gradle / Ivy

There is a newer version: 2.24.3.5
Show newest version
/**
 * Copyright 2017-2023 Open Text
 *
 * The only warranties for products and services of Open Text and
 * its affiliates and licensors (“Open Text”) are as may be set forth
 * in the express warranty statements accompanying such products and services.
 * Nothing herein should be construed as constituting an additional warranty.
 * Open Text shall not be liable for technical or editorial errors or
 * omissions contained herein. The information contained herein is subject
 * to change without notice.
 *
 * Except as specifically indicated otherwise, this document contains
 * confidential information and a valid license is required for possession,
 * use or copying. If this work is provided to the U.S. Government,
 * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
 * Computer Software Documentation, and Technical Data for Commercial Items are
 * licensed to the U.S. Government under vendor's standard commercial license.
 *
 * 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.hp.octane.integrations.services.entities;

import com.hp.octane.integrations.OctaneSDK;
import com.hp.octane.integrations.dto.DTOFactory;
import com.hp.octane.integrations.dto.connectivity.HttpMethod;
import com.hp.octane.integrations.dto.connectivity.OctaneRequest;
import com.hp.octane.integrations.dto.connectivity.OctaneResponse;
import com.hp.octane.integrations.dto.entities.*;
import com.hp.octane.integrations.exceptions.OctaneBulkException;
import com.hp.octane.integrations.exceptions.OctaneRestException;
import com.hp.octane.integrations.services.rest.OctaneRestClient;
import com.hp.octane.integrations.services.rest.RestService;
import com.hp.octane.integrations.utils.SdkStringUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.http.HttpStatus;
import org.apache.http.entity.ContentType;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.regex.Pattern;

import static com.hp.octane.integrations.services.rest.RestService.ACCEPT_HEADER;
import static com.hp.octane.integrations.services.rest.RestService.CONTENT_TYPE_HEADER;

/**
 * Default implementation of tests service
 */

final class EntitiesServiceImpl implements EntitiesService {
    private static final Logger logger = LogManager.getLogger(EntitiesServiceImpl.class);
    private static final DTOFactory dtoFactory = DTOFactory.getInstance();

    private final OctaneSDK.SDKServicesConfigurer configurer;
    private final RestService restService;

    private static final String FILTERING_FRAGMENT = "query={query}";
    private static final String FIELDS_FRAGMENT = "fields={fields}";
    private static final String PAGING_FRAGMENT = "offset={offset}&limit={limit}";
    private static final String ORDER_BY_FRAGMENT = "order_by={order}";
    private static final String URI_PARAM_ENCODING = "UTF-8";
    private static final int MAX_GET_LIMIT = 1000;
	private static final int MAX_UPDATE_LIMIT = 200;

    EntitiesServiceImpl(OctaneSDK.SDKServicesConfigurer configurer, RestService restService) {
        if (configurer == null) {
            throw new IllegalArgumentException("invalid configurer");
        }
        if (restService == null) {
            throw new IllegalArgumentException("rest service MUST NOT be null");
        }
        this.configurer = configurer;
        this.restService = restService;
        logger.info(configurer.octaneConfiguration.getLocationForLog() + "initialized SUCCESSFULLY");
    }

    @Override
    public List deleteEntitiesByIds(Long workspaceId, String entityCollectionName, Collection entitiesIds) {

        //CREATE DELETE CONDITION
        if (entitiesIds == null || entitiesIds.isEmpty()) {
            return null;
        }
        String deleteCondition = QueryHelper.conditionIn("id", entitiesIds, true);
        return deleteEntities(workspaceId, entityCollectionName, Collections.singletonList(deleteCondition));
    }

    @Override
    public List deleteEntities(Long workspaceId, String entityCollectionName, Collection conditions) {
        //SEND REQUEST
        OctaneRestClient octaneRestClient = restService.obtainOctaneRestClient();
        Map headers = new HashMap<>();
        headers.put(ACCEPT_HEADER, ContentType.APPLICATION_JSON.getMimeType());
        headers.put(OctaneRestClient.CLIENT_TYPE_HEADER, OctaneRestClient.CLIENT_TYPE_VALUE);
        String url = buildEntityUrl(workspaceId, entityCollectionName, conditions, null, null, null, null);
        OctaneRequest request = dtoFactory.newDTO(OctaneRequest.class)
                .setMethod(HttpMethod.DELETE)
                .setUrl(url)
                .setHeaders(headers);
        OctaneResponse response = executeRequest(octaneRestClient, request);
        ResponseEntityList responseEntityList = parseBody(HttpStatus.SC_OK, response);
        return responseEntityList.getData();
    }

    @Override
    public List updateEntities(Long workspaceId, String entityCollectionName, List entities) {
        List results = new ArrayList<>();
        ListUtils.partition(entities, MAX_UPDATE_LIMIT).forEach(list -> {
            EntityList entitiesForUpdate = dtoFactory.newDTO(EntityList.class);
            entitiesForUpdate.setData(list);
            String jsonData = dtoFactory.dtoToJson(entitiesForUpdate);
            List temp = updateEntities(workspaceId, entityCollectionName, jsonData);
            results.addAll(temp);
        });
        return results;
    }

    @Override
    public List updateEntities(Long workspaceId, String entityCollectionName, String jsonData) {
        OctaneRestClient octaneRestClient = restService.obtainOctaneRestClient();
        Map headers = new HashMap<>();
        headers.put(ACCEPT_HEADER, ContentType.APPLICATION_JSON.getMimeType());
        headers.put(CONTENT_TYPE_HEADER, ContentType.APPLICATION_JSON.getMimeType());
        headers.put(OctaneRestClient.CLIENT_TYPE_HEADER, OctaneRestClient.CLIENT_TYPE_VALUE);

        String url = buildEntityUrl(workspaceId, entityCollectionName, null, null, null, null, null);

        OctaneRequest request = dtoFactory.newDTO(OctaneRequest.class)
                .setMethod(HttpMethod.PUT)
                .setUrl(url)
                .setBody(jsonData)
                .setHeaders(headers);
        OctaneResponse response = executeRequest(octaneRestClient, request);
        ResponseEntityList responseEntityList = parseBody(HttpStatus.SC_OK, response);
        return responseEntityList.getData();
    }

    @Override
    public List postEntities(Long workspaceId, String entityCollectionName, List entities) {
		return postEntities(workspaceId, entityCollectionName, entities, null);
    }

    @Override
    public List postEntities(Long workspaceId, String entityCollectionName, List entities, Collection fields) {
		return postEntities(workspaceId, entityCollectionName, entities, fields,Collections.emptyMap());
    }

    @Override
    public List postEntities(Long workspaceId, String entityCollectionName, List entities, Collection fields, Map serviceArgument){
        List results = new ArrayList<>();
        ListUtils.partition(entities, MAX_UPDATE_LIMIT).forEach(list -> {
            EntityList entitiesForUpdate = dtoFactory.newDTO(EntityList.class);
            entitiesForUpdate.setData(list);
            String jsonData = dtoFactory.dtoToJson(entitiesForUpdate);
            List temp = postEntities(workspaceId, entityCollectionName, jsonData, fields,serviceArgument);
            results.addAll(temp);
        });
        return results;
    }

    @Override
    public List postEntities(Long workspaceId, String entityCollectionName, String jsonData) {
        return postEntities(workspaceId, entityCollectionName, jsonData, null);
    }

    @Override
    public List postEntities(Long workspaceId, String entityCollectionName, String jsonData, Collection fields) {
        return postEntities(workspaceId, entityCollectionName, jsonData, null,Collections.EMPTY_MAP);
    }

    @Override
    public List postEntities(Long workspaceId, String entityCollectionName, String jsonData, Collection fields,Map serviceArgument) {
        OctaneRestClient octaneRestClient = restService.obtainOctaneRestClient();
        Map headers = new HashMap<>();
        headers.put(ACCEPT_HEADER, ContentType.APPLICATION_JSON.getMimeType());
        headers.put(CONTENT_TYPE_HEADER, ContentType.APPLICATION_JSON.getMimeType());
        headers.put(OctaneRestClient.CLIENT_TYPE_HEADER, OctaneRestClient.CLIENT_TYPE_VALUE);

        String url = buildEntityUrl(workspaceId, entityCollectionName, null, fields, null, null, null,serviceArgument);
        OctaneRequest request = dtoFactory.newDTO(OctaneRequest.class)
                .setMethod(HttpMethod.POST)
                .setUrl(url)
                .setBody(jsonData)
                .setHeaders(headers);
        OctaneResponse response = executeRequest(octaneRestClient, request);
        ResponseEntityList responseEntityList = parseBody(HttpStatus.SC_CREATED, response);
        return responseEntityList.getData();
    }

    @Override
    public List getEntities(Long workspaceId, String entityCollectionName, Collection conditions, Collection fields) {
        return getEntities(workspaceId,entityCollectionName,conditions,null,fields);
    }

    @Override
    public List getEntities(Long workspaceId, String entityCollectionName, Collection conditions, String orderBy, Collection fields) {

        List result = new ArrayList<>();
        int limit = MAX_GET_LIMIT;
        boolean fetchedAll = false;
        while (!fetchedAll) {
            String url = buildEntityUrl(workspaceId, entityCollectionName, conditions, fields, result.size(), limit, orderBy);
            ResponseEntityList responseEntityList = getPagedEntities(url);
            result.addAll(responseEntityList.getData());
            fetchedAll = responseEntityList.getData().isEmpty() || responseEntityList.getTotalCount() == 0 || responseEntityList.getTotalCount() == result.size();
        }

        return result;
    }

    @Override
    public List getEntitiesByIds(Long workspaceId, String collectionName, Collection ids) {
        return getEntitiesByIds(workspaceId,collectionName,ids,null);
    }

    @Override
    public List getEntitiesByIds(Long workspaceId, String collectionName, Collection ids, Collection fields) {
        if (ids == null || ids.size() == 0) {
            return new LinkedList<>();
        }
        int limit = 100;
        if (ids.size() > limit) {
            throw new IllegalArgumentException("List of ids is too long. Only " + limit + " values are allowed.");
        }

        List conditions = new LinkedList();
        conditions.add(QueryHelper.conditionIn(EntityConstants.Base.ID_FIELD, ids, true));

        String url = buildEntityUrl(workspaceId, collectionName, conditions, fields, 0, limit, null);
        ResponseEntityList result = getPagedEntities(url);
        return result.getData();
    }

    @Override
    public ResponseEntityList getPagedEntities(String url) {
        OctaneRestClient octaneRestClient = restService.obtainOctaneRestClient();
        Map headers = new HashMap<>();
        headers.put(ACCEPT_HEADER, ContentType.APPLICATION_JSON.getMimeType());
        headers.put(OctaneRestClient.CLIENT_TYPE_HEADER, OctaneRestClient.CLIENT_TYPE_VALUE);

        OctaneRequest request = dtoFactory.newDTO(OctaneRequest.class)
                .setMethod(HttpMethod.GET)
                .setUrl(url)
                .setHeaders(headers);
        OctaneResponse response = executeRequest(octaneRestClient, request);

        ResponseEntityList pagedEntityList = parseBody(HttpStatus.SC_OK, response);

        return pagedEntityList;
    }

    private OctaneResponse executeRequest(OctaneRestClient octaneRestClient, OctaneRequest request) {
        try {
            return octaneRestClient.execute(request);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    private static ResponseEntityList parseBody(int expectedResult, OctaneResponse response) {
        String body = response.getBody();
        if (response.getStatus() == expectedResult) {
            return dtoFactory.dtoFromJson(body, ResponseEntityList.class);
        } else {
            try {
                if (body.contains("exceeds_total_count")) {
                    OctaneBulkExceptionData data = dtoFactory.dtoFromJson(body, OctaneBulkExceptionData.class);
                    throw new OctaneBulkException(response.getStatus(), data);
                } else {
                    OctaneRestExceptionData data = dtoFactory.dtoFromJson(body, OctaneRestExceptionData.class);
                    throw new OctaneRestException(response.getStatus(), data);
                }
            } catch (OctaneRestException | OctaneBulkException ex1) {
                throw ex1;
            } catch (Exception ex2) {
                throw new RuntimeException("The request failed : " + body, ex2);
            }
        }
    }

    public String buildEntityUrl(Long workspaceId, String collection, Collection conditions, Collection fields, Integer offset, Integer limit, String orderBy) {
        return buildEntityUrl(workspaceId, collection, conditions, fields, offset, limit, orderBy,Collections.EMPTY_MAP);
    }

    public String buildEntityUrl(Long workspaceId, String collection, Collection conditions, Collection fields, Integer offset, Integer limit, String orderBy,Map serviceArgument) {

        StringBuilder template = new StringBuilder(configurer.octaneConfiguration.getUrl());
        template.append("/api/shared_spaces/");
        template.append(configurer.octaneConfiguration.getSharedSpace());
        if (workspaceId != null) {
            template.append("/workspaces/");
            template.append(workspaceId);
        }

        template.append("/");
        template.append(collection);
        template.append("?");

        Map params = new HashMap<>();
        if (offset != null && limit != null) {
            params.put("offset", offset);
            params.put("limit", limit);
            template.append("&" + PAGING_FRAGMENT);
        }

        if (conditions != null && !conditions.isEmpty()) {
            StringBuilder expr = new StringBuilder();
            for (String condition : conditions) {
                if (expr.length() > 0) {
                    expr.append(";");
                }
                expr.append(condition);
            }
            params.put("query", "\"" + expr.toString() + "\"");
            template.append("&" + FILTERING_FRAGMENT);
        }

        if (fields != null && !fields.isEmpty()) {
            params.put("fields", SdkStringUtils.join(fields, ","));
            template.append("&" + FIELDS_FRAGMENT);
        }

        if (SdkStringUtils.isNotEmpty(orderBy)) {
            params.put("order", orderBy);
            template.append("&" + ORDER_BY_FRAGMENT);
        }

        if(!serviceArgument.isEmpty()){
            serviceArgument.forEach((key,value) ->{
                params.put(key,value);
                template.append("&" + key + "={" +key +"}");
            });
        }
        return resolveTemplate(template.toString(), params);
    }

    private static String resolveTemplate(String template, Map params) {
        String result = template;
        for (Map.Entry param : params.entrySet()) {
            result = result.replaceAll(Pattern.quote("{" + param.getKey() + "}"), encodeParam(param.getValue() == null ? "" : param.getValue().toString()));
        }
        return result;
    }

    private static String encodeParam(String param) {
        try {
            return URLEncoder.encode(param, URI_PARAM_ENCODING).replace("+", "%20");
        } catch (UnsupportedEncodingException e) {
            throw new IllegalStateException("Unsupported encoding used for URI parameter encoding.", e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy