updates to check versions on process query params

This commit is contained in:
Tim Chamberlain
2025-05-15 12:56:10 -05:00
parent 2491523a6b
commit 32fde00b96
3 changed files with 125 additions and 87 deletions

View File

@ -0,0 +1,106 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2023. Kingsrook, LLC
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
* contact@kingsrook.com
* https://github.com/Kingsrook/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.kingsrook.qqq.api.actions;
import com.kingsrook.qqq.api.model.APIVersionRange;
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaData;
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaDataContainer;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
import com.kingsrook.qqq.backend.core.utils.ObjectUtils;
import com.kingsrook.qqq.backend.core.utils.StringUtils;
import org.apache.commons.lang.BooleanUtils;
/*******************************************************************************
** utility methods for working with fields
**
*******************************************************************************/
public class ApiFieldUtils
{
/*******************************************************************************
**
*******************************************************************************/
public static boolean isIncluded(String apiName, QFieldMetaData field)
{
ApiFieldMetaData apiFieldMetaData = getApiFieldMetaData(apiName, field);
if(apiFieldMetaData != null && BooleanUtils.isTrue(apiFieldMetaData.getIsExcluded()))
{
return (false);
}
return (true);
}
/*******************************************************************************
**
*******************************************************************************/
public static APIVersionRange getApiVersionRangeForRemovedField(String apiName, QFieldMetaData field)
{
ApiFieldMetaData apiFieldMetaData = getApiFieldMetaData(apiName, field);
if(apiFieldMetaData != null && apiFieldMetaData.getInitialVersion() != null)
{
if(StringUtils.hasContent(apiFieldMetaData.getFinalVersion()))
{
return (APIVersionRange.betweenAndIncluding(apiFieldMetaData.getInitialVersion(), apiFieldMetaData.getFinalVersion()));
}
else
{
throw (new IllegalStateException("RemovedApiFieldMetaData for field [" + field.getName() + "] did not specify a finalVersion."));
}
}
else
{
throw (new IllegalStateException("RemovedApiFieldMetaData for field [" + field.getName() + "] did not specify an initialVersion."));
}
}
/*******************************************************************************
**
*******************************************************************************/
public static APIVersionRange getApiVersionRange(String apiName, QFieldMetaData field)
{
ApiFieldMetaData apiFieldMetaData = getApiFieldMetaData(apiName, field);
if(apiFieldMetaData != null && apiFieldMetaData.getInitialVersion() != null)
{
return (APIVersionRange.afterAndIncluding(apiFieldMetaData.getInitialVersion()));
}
return (APIVersionRange.none());
}
/*******************************************************************************
**
*******************************************************************************/
public static ApiFieldMetaData getApiFieldMetaData(String apiName, QFieldMetaData field)
{
return ObjectUtils.tryAndRequireNonNullElse(() -> ApiFieldMetaDataContainer.of(field).getApiFieldMetaData(apiName), new ApiFieldMetaData());
}
}

View File

@ -726,7 +726,7 @@ public class GenerateOpenApiSpecAction extends AbstractQActionFunction<GenerateO
ApiProcessMetaData apiProcessMetaData = pair.getA(); ApiProcessMetaData apiProcessMetaData = pair.getA();
QProcessMetaData processMetaData = pair.getB(); QProcessMetaData processMetaData = pair.getB();
addProcessEndpoints(qInstance, apiInstanceMetaData, basePath, openAPI, tableProcessesTag, apiProcessMetaData, processMetaData); addProcessEndpoints(qInstance, apiInstanceMetaData, basePath, openAPI, tableProcessesTag, apiProcessMetaData, processMetaData, apiVersion);
usedProcessNames.add(processMetaData.getName()); usedProcessNames.add(processMetaData.getName());
} }
@ -761,7 +761,7 @@ public class GenerateOpenApiSpecAction extends AbstractQActionFunction<GenerateO
.withName(tag) .withName(tag)
.withDescription(tag)); .withDescription(tag));
addProcessEndpoints(qInstance, apiInstanceMetaData, basePath, openAPI, tag, apiProcessMetaData, processMetaData); addProcessEndpoints(qInstance, apiInstanceMetaData, basePath, openAPI, tag, apiProcessMetaData, processMetaData, apiVersion);
usedProcessNames.add(processMetaData.getName()); usedProcessNames.add(processMetaData.getName());
} }
@ -807,14 +807,14 @@ public class GenerateOpenApiSpecAction extends AbstractQActionFunction<GenerateO
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/
private void addProcessEndpoints(QInstance qInstance, ApiInstanceMetaData apiInstanceMetaData, String basePath, OpenAPI openAPI, String tag, ApiProcessMetaData apiProcessMetaData, QProcessMetaData processMetaData) private void addProcessEndpoints(QInstance qInstance, ApiInstanceMetaData apiInstanceMetaData, String basePath, OpenAPI openAPI, String tag, ApiProcessMetaData apiProcessMetaData, QProcessMetaData processMetaData, APIVersion apiVersion)
{ {
String processApiPath = ApiProcessUtils.getProcessApiPath(qInstance, processMetaData, apiProcessMetaData, apiInstanceMetaData); String processApiPath = ApiProcessUtils.getProcessApiPath(qInstance, processMetaData, apiProcessMetaData, apiInstanceMetaData);
/////////////////////////// ///////////////////////////
// do the process itself // // do the process itself //
/////////////////////////// ///////////////////////////
Path path = generateProcessSpecPathObject(apiInstanceMetaData, apiProcessMetaData, processMetaData, ListBuilder.of(tag)); Path path = generateProcessSpecPathObject(apiInstanceMetaData, apiProcessMetaData, processMetaData, ListBuilder.of(tag), apiVersion);
openAPI.getPaths().put(basePath + processApiPath, path); openAPI.getPaths().put(basePath + processApiPath, path);
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
@ -872,7 +872,7 @@ public class GenerateOpenApiSpecAction extends AbstractQActionFunction<GenerateO
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/
private Path generateProcessSpecPathObject(ApiInstanceMetaData apiInstanceMetaData, ApiProcessMetaData apiProcessMetaData, QProcessMetaData processMetaData, List<String> tags) private Path generateProcessSpecPathObject(ApiInstanceMetaData apiInstanceMetaData, ApiProcessMetaData apiProcessMetaData, QProcessMetaData processMetaData, List<String> tags, APIVersion apiVersion)
{ {
String description = apiProcessMetaData.getDescription(); String description = apiProcessMetaData.getDescription();
if(!StringUtils.hasContent(description)) if(!StringUtils.hasContent(description))
@ -927,7 +927,10 @@ public class GenerateOpenApiSpecAction extends AbstractQActionFunction<GenerateO
for(QFieldMetaData field : CollectionUtils.nonNullList(queryStringParams.getFields())) for(QFieldMetaData field : CollectionUtils.nonNullList(queryStringParams.getFields()))
{ {
parameters.add(processFieldToParameter(apiInstanceMetaData, field).withIn("query")); if(ApiFieldUtils.isIncluded(apiName, field) && ApiFieldUtils.getApiVersionRange(apiName, field).includes(apiVersion))
{
parameters.add(processFieldToParameter(apiInstanceMetaData, field).withIn("query"));
}
} }
} }

View File

@ -31,11 +31,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import com.kingsrook.qqq.api.model.APIVersion; import com.kingsrook.qqq.api.model.APIVersion;
import com.kingsrook.qqq.api.model.APIVersionRange;
import com.kingsrook.qqq.api.model.actions.GetTableApiFieldsInput; import com.kingsrook.qqq.api.model.actions.GetTableApiFieldsInput;
import com.kingsrook.qqq.api.model.actions.GetTableApiFieldsOutput; import com.kingsrook.qqq.api.model.actions.GetTableApiFieldsOutput;
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaData; import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaData;
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaDataContainer;
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData; import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer; import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer;
import com.kingsrook.qqq.backend.core.actions.AbstractQActionFunction; import com.kingsrook.qqq.backend.core.actions.AbstractQActionFunction;
@ -45,8 +43,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import com.kingsrook.qqq.backend.core.utils.ObjectUtils; import com.kingsrook.qqq.backend.core.utils.ObjectUtils;
import com.kingsrook.qqq.backend.core.utils.StringUtils;
import org.apache.commons.lang.BooleanUtils;
/******************************************************************************* /*******************************************************************************
@ -160,7 +156,7 @@ public class GetTableApiFieldsAction extends AbstractQActionFunction<GetTableApi
fieldList.sort(Comparator.comparing(QFieldMetaData::getLabel)); fieldList.sort(Comparator.comparing(QFieldMetaData::getLabel));
for(QFieldMetaData field : fieldList) for(QFieldMetaData field : fieldList)
{ {
if(!isExcluded(input.getApiName(), field) && getApiVersionRange(input.getApiName(), field).includes(version)) if(ApiFieldUtils.isIncluded(input.getApiName(), field) && ApiFieldUtils.getApiVersionRange(input.getApiName(), field).includes(version))
{ {
fields.add(field); fields.add(field);
} }
@ -171,7 +167,7 @@ public class GetTableApiFieldsAction extends AbstractQActionFunction<GetTableApi
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
for(QFieldMetaData field : CollectionUtils.nonNullList(getRemovedApiFields(input.getApiName(), table))) for(QFieldMetaData field : CollectionUtils.nonNullList(getRemovedApiFields(input.getApiName(), table)))
{ {
if(!isExcluded(input.getApiName(), field) && getApiVersionRangeForRemovedField(input.getApiName(), field).includes(version)) if(ApiFieldUtils.isIncluded(input.getApiName(), field) && ApiFieldUtils.getApiVersionRangeForRemovedField(input.getApiName(), field).includes(version))
{ {
fields.add(field); fields.add(field);
} }
@ -184,73 +180,6 @@ public class GetTableApiFieldsAction extends AbstractQActionFunction<GetTableApi
/*******************************************************************************
**
*******************************************************************************/
private boolean isExcluded(String apiName, QFieldMetaData field)
{
ApiFieldMetaData apiFieldMetaData = getApiFieldMetaData(apiName, field);
if(apiFieldMetaData != null && BooleanUtils.isTrue(apiFieldMetaData.getIsExcluded()))
{
return (true);
}
return (false);
}
/*******************************************************************************
**
*******************************************************************************/
private APIVersionRange getApiVersionRangeForRemovedField(String apiName, QFieldMetaData field)
{
ApiFieldMetaData apiFieldMetaData = getApiFieldMetaData(apiName, field);
if(apiFieldMetaData != null && apiFieldMetaData.getInitialVersion() != null)
{
if(StringUtils.hasContent(apiFieldMetaData.getFinalVersion()))
{
return (APIVersionRange.betweenAndIncluding(apiFieldMetaData.getInitialVersion(), apiFieldMetaData.getFinalVersion()));
}
else
{
throw (new IllegalStateException("RemovedApiFieldMetaData for field [" + field.getName() + "] did not specify a finalVersion."));
}
}
else
{
throw (new IllegalStateException("RemovedApiFieldMetaData for field [" + field.getName() + "] did not specify an initialVersion."));
}
}
/*******************************************************************************
**
*******************************************************************************/
private APIVersionRange getApiVersionRange(String apiName, QFieldMetaData field)
{
ApiFieldMetaData apiFieldMetaData = getApiFieldMetaData(apiName, field);
if(apiFieldMetaData != null && apiFieldMetaData.getInitialVersion() != null)
{
return (APIVersionRange.afterAndIncluding(apiFieldMetaData.getInitialVersion()));
}
return (APIVersionRange.none());
}
/*******************************************************************************
**
*******************************************************************************/
private static ApiFieldMetaData getApiFieldMetaData(String apiName, QFieldMetaData field)
{
return ObjectUtils.tryAndRequireNonNullElse(() -> ApiFieldMetaDataContainer.of(field).getApiFieldMetaData(apiName), new ApiFieldMetaData());
}
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/