ReadyAPI-在无头模式下请求访问令牌失败,无法在 CI/CD 管道中检索 oauth 2 令牌

如何解决ReadyAPI-在无头模式下请求访问令牌失败,无法在 CI/CD 管道中检索 oauth 2 令牌

我正在使用以下代码生成 accessToken。

import com.eviware.soapui.impl.rest.actions.oauth.OltuOAuth2ClientFacade;
    import com.eviware.soapui.support.editor.inspectors.auth.TokenType;
    import com.eviware.soapui.model.support.ModelSupport;
    
    // Set up variables
    def project = ModelSupport.getModelItemProject(context.getModelItem());
    def authProfile = project.getAuthRepository().getEntry("user");
    def oldToken = authProfile.getAccessToken();
    def tokenType = TokenType.ACCESS;
    //log.info("OLD TOKEN: " + oldToken);
    
    // Create a facade object
    def oAuthFacade = new OltuOAuth2ClientFacade(tokenType);
    
    // Request an access token in headless mode
    oAuthFacade.requestAccessToken(authProfile,true,true);
    
    // Wait until the access token gets updated
    //while(oldToken == authProfile.getAccessToken()) {
    //}
    //The sleep method can be used instead of a while loop
    //sleep(3000);
    
    for(int i = 0; i<=6000; i++){
    if(oldToken != authProfile.getAccessToken()){
    break
    }
    sleep(1)
    }
    
    // Post the info to the log
    def token = authProfile.getAccessToken();
    log.info("NEW TOKEN: " + authProfile.getAccessToken());
    
    testRunner.testCase.testSuite.project.setPropertyValue( "accessToken",token )

此代码在笔记本电脑上运行没有问题。但是在 CI/CD 管道中配置时,代码失败并显示错误消息:-

发生错误 [/tmp/JxBrowser/7.12/libbrowsercore_toolkit.so: libX11.so.6: 无法打开共享对象文件:没有这样的文件或目录],详情请参阅错误日志 Groovy Script 测试步骤【Groovy Script 3】的脚本中出现错误: [错误日志] java.lang.UnsatisfiedLinkError: /tmp/JxBrowser/7.12/libbrowsercore_toolkit.so: libX11.so.6: 无法打开共享对象文件: 没有那个文件或目录 java.lang.UnsatisfiedLinkError:/tmp/JxBrowser/7.12/libbrowsercore_toolkit.so:libX11.so.6:无法打开共享对象文件:没有这样的文件或目录

解决方法

我能够通过将以下代码放在“安装脚本”中来解决该问题。 并且脚本在过去 2 天的管道中运行没有任何问题。

import com.eviware.soapui.impl.wsdl.submit.filters.AbstractRequestFilter
import com.eviware.soapui.impl.wsdl.submit.filters.OAuth2RequestFilter
import com.eviware.soapui.impl.wsdl.submit.RequestTransportRegistry
RequestTransportRegistry.getTransport("https").replaceRequestFilter(OAuth2RequestFilter,new modifiedOAuth2RequestFilter())


/*
 *   below is a copy of class OAuth2RequestFilter with a new name as retrieved from 
 *   https://github.com/SmartBear/soapui/blob/next/soapui/src/main/java/com/eviware/soapui/impl/wsdl/submit/filters/OAuth2RequestFilter.java
 *   except that the ACCESS_TOKEN_RETRIEVAL_TIMEOUT value has been changed from 5000 to 10000
 */   

import com.eviware.soapui.config.TimeUnitConfig;
import com.eviware.soapui.impl.rest.OAuth2Profile;
import com.eviware.soapui.impl.rest.OAuth2ProfileContainer;
import com.eviware.soapui.impl.rest.RestRequestInterface;
import com.eviware.soapui.impl.rest.actions.oauth.OAuth2ClientFacade;
import com.eviware.soapui.impl.rest.actions.oauth.OltuOAuth2ClientFacade;
import com.eviware.soapui.impl.support.AbstractHttpRequest;
import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
import com.eviware.soapui.model.iface.SubmitContext;
import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.TimeUtils;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.log4j.Logger;

import static com.eviware.soapui.config.CredentialsConfig.AuthType.O_AUTH_2_0;

public class modifiedOAuth2RequestFilter extends AbstractRequestFilter {
    private static final int ACCESS_TOKEN_RETRIEVAL_TIMEOUT = 10000;
    
    // intentionally left non-final to facilitate testing,but should not be modified in production!
    private static Logger log = Logger.getLogger(OAuth2RequestFilter.class);

    /* setLog() and getLog() should only be used for testing */

    static Logger getLog() {
        return log;
    }

    static void setLog(Logger newLog) {
        log = newLog;
    }

    @Override
    public void filterRestRequest(SubmitContext context,RestRequestInterface request) {

        HttpRequestBase httpMethod = (HttpRequestBase) context.getProperty(BaseHttpRequestTransport.HTTP_METHOD);
    log.info O_AUTH_2_0.toString()
        if (O_AUTH_2_0.toString().equals(request.getAuthType())) {
            OAuth2ProfileContainer profileContainer = request.getResource().getService().getProject()
                    .getOAuth2ProfileContainer();
            OAuth2Profile profile = profileContainer.getProfileByName(((AbstractHttpRequest) request).getSelectedAuthProfile());
            if (profile == null || StringUtils.isNullOrEmpty(profile.getAccessToken())) {
                return;
            }
            OAuth2ClientFacade oAuth2Client = getOAuth2ClientFacade();

            if (accessTokenIsExpired(profile)) {
                if (profile.shouldReloadAccessTokenAutomatically()) {
                    reloadAccessToken(profile,oAuth2Client);
                } else {
                    profile.setAccessTokenStatus(OAuth2Profile.AccessTokenStatus.EXPIRED);
                }
            }
            oAuth2Client.applyAccessToken(profile,httpMethod,request.getRequestContent());
        } 
    }

    protected OAuth2ClientFacade getOAuth2ClientFacade() {
        return new OltuOAuth2ClientFacade();
    }

   
    private boolean accessTokenIsExpired(OAuth2Profile profile) {
        long currentTime = TimeUtils.getCurrentTimeInSeconds();
        long issuedTime = profile.getAccessTokenIssuedTime();
        long expirationTime;

        if (profile.useManualAccessTokenExpirationTime()) {
            String expirationTimeString = profile.getManualAccessTokenExpirationTime() == null ? "" : profile.getManualAccessTokenExpirationTime();
            String expandedValue = PropertyExpander.expandProperties(profile.getContainer().getProject(),expirationTimeString);
            expirationTime = convertExpirationTimeToSeconds(expandedValue,profile.getManualAccessTokenExpirationTimeUnit());
        } else {
            expirationTime = profile.getAccessTokenExpirationTime();
        }

        //10 second buffer to make sure that the access token doesn't expire by the time request is sent
        return !(issuedTime <= 0 || expirationTime <= 0) && expirationTime < (currentTime + 10) - issuedTime;
    }

    private long convertExpirationTimeToSeconds(String expirationTimeString,TimeUnitConfig.Enum timeUnit) throws IllegalArgumentException {
        long expirationTime;
        try {
            expirationTime = Long.valueOf(expirationTimeString.trim());
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Manual expiration time cannot be parsed due to invalid characters." +
                    "Please review it and make sure it is set correctly.",e);
        }
        if (timeUnit.equals(TimeUnitConfig.HOURS)) {
            return expirationTime * 3600;
        } else if (timeUnit.equals(TimeUnitConfig.MINUTES)) {
            return expirationTime * 60;
        } else {
            return expirationTime;
        }
    }

    private void reloadAccessToken(OAuth2Profile profile,OAuth2ClientFacade oAuth2Client) {
        try {
            if (profile.getRefreshToken() != null) {
                log.info("The access token has expired,trying to refresh it.");
                oAuth2Client.refreshAccessToken(profile);
                log.info("The access token has been refreshed successfully.");
            } else {
                if (profile.hasAutomationJavaScripts()) {
                    log.info("The access token has expired,trying to retrieve a new one with JavaScript automation.");
                    oAuth2Client.requestAccessToken(profile);
                    profile.waitForAccessTokenStatus(OAuth2Profile.AccessTokenStatus.RETRIEVED_FROM_SERVER,ACCESS_TOKEN_RETRIEVAL_TIMEOUT);
                    if (profile.getAccessTokenStatus() == OAuth2Profile.AccessTokenStatus.RETRIEVED_FROM_SERVER) {
                        log.info("A new access token has been retrieved successfully.");
                    } else {
                        log.info("OAuth2 access token retrieval timed out after " + ACCESS_TOKEN_RETRIEVAL_TIMEOUT + " ms");
                        throw new RuntimeException("OAuth2 access token retrieval timed out after " + ACCESS_TOKEN_RETRIEVAL_TIMEOUT + " ms");
                    }
                } else {
                    log.info("No automation JavaScripts added to OAuth2 profile – cannot retrieve new access token");
                    throw new RuntimeException("No automation JavaScripts added to OAuth2 profile – cannot retrieve new access token");
                }
            }
        } catch (Exception e) {
            //Propagate it up so that it is shown as a failure message in test case log
            throw new RuntimeException("Unable to refresh expired access token.",e);
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-