Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
import com.alipay.sofa.ark.api.ArkClient;
import com.alipay.sofa.ark.api.ClientResponse;
import com.alipay.sofa.ark.api.ResponseCode;
import com.alipay.sofa.ark.common.util.BizIdentityUtils;
import com.alipay.sofa.ark.common.util.FileUtils;
import com.alipay.sofa.ark.common.util.StringUtils;
import com.alipay.sofa.ark.spi.model.Biz;
import com.alipay.sofa.ark.spi.service.biz.BizFactoryService;
import com.alipay.sofa.koupleless.arklet.core.command.builtin.BuiltinCommand;
import com.alipay.sofa.koupleless.arklet.core.command.coordinate.BizOpsPodCoordinator;
import com.alipay.sofa.koupleless.arklet.core.command.meta.AbstractCommandHandler;
import com.alipay.sofa.koupleless.arklet.core.command.meta.Command;
import com.alipay.sofa.koupleless.arklet.core.command.meta.Output;
Expand Down Expand Up @@ -69,6 +71,10 @@ public Output<InstallBizClientResponse> handle(Input input) {
installBizClientResponse
.setElapsedSpace(metaSpaceMXBean.getUsage().getUsed() - startSpace);
if (ResponseCode.SUCCESS.equals(installBizClientResponse.getCode())) {
String bizIdentity = BizIdentityUtils.generateBizIdentity(input.getBizName(),
input.getBizVersion());
String bizModelVersion = input.getBizModelVersion();
BizOpsPodCoordinator.save(bizIdentity, bizModelVersion);
return Output.ofSuccess(installBizClientResponse);
} else {
return Output.ofFailed(installBizClientResponse, "install biz not success!");
Expand Down Expand Up @@ -174,4 +180,4 @@ public static class InstallBizClientResponse extends ClientResponse {
private long elapsedSpace;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@

import com.alipay.sofa.ark.api.ClientResponse;
import com.alipay.sofa.ark.api.ResponseCode;
import com.alipay.sofa.ark.common.util.BizIdentityUtils;
import com.alipay.sofa.ark.common.util.StringUtils;
import com.alipay.sofa.koupleless.arklet.core.command.builtin.BuiltinCommand;
import com.alipay.sofa.koupleless.arklet.core.command.builtin.handler.UninstallBizHandler.Input;
import com.alipay.sofa.koupleless.arklet.core.command.coordinate.BizOpsPodCoordinator;
import com.alipay.sofa.koupleless.arklet.core.command.meta.AbstractCommandHandler;
import com.alipay.sofa.koupleless.arklet.core.command.meta.Command;
import com.alipay.sofa.koupleless.arklet.core.command.meta.Output;
import com.alipay.sofa.koupleless.arklet.core.command.meta.bizops.ArkBizMeta;
import com.alipay.sofa.koupleless.arklet.core.command.meta.bizops.ArkBizOps;
import com.alipay.sofa.koupleless.arklet.core.common.exception.ArkletRuntimeException;
import com.alipay.sofa.koupleless.arklet.core.common.exception.CommandValidationException;
import com.alipay.sofa.koupleless.common.log.ArkletLogger;
import com.alipay.sofa.koupleless.common.log.ArkletLoggerFactory;

/**
* <p>UninstallBizHandler class.</p>
Expand All @@ -39,13 +43,25 @@
public class UninstallBizHandler extends AbstractCommandHandler<Input, ClientResponse>
implements ArkBizOps {

private static final ArkletLogger LOGGER = ArkletLoggerFactory.getDefaultLogger();

/** {@inheritDoc} */
@Override
public Output<ClientResponse> handle(Input input) {
try {
String bizIdentity = BizIdentityUtils.generateBizIdentity(input.getBizName(),
input.getBizVersion());
String bizModelVersion = input.getBizModelVersion();
if (!BizOpsPodCoordinator.canAccess(bizIdentity, bizModelVersion)) {
LOGGER.error(
"can not access biz because the command is expired. bizIdentity: {}, bizModelVersion: {}",
bizIdentity, bizModelVersion);
return Output.ofFailed("can not access biz because the command is expired");
}
ClientResponse res = getOperationService().uninstall(input.getBizName(),
input.getBizVersion());
if (ResponseCode.SUCCESS.equals(res.getCode())) {
BizOpsPodCoordinator.remove(bizIdentity, bizModelVersion);
return Output.ofSuccess(res);
} else {
return Output.ofFailed(res, "uninstall biz not success!");
Expand Down Expand Up @@ -73,4 +89,4 @@ public void validate(Input input) throws CommandValidationException {
public static class Input extends ArkBizMeta {
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.alipay.sofa.koupleless.arklet.core.command.coordinate;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.alipay.sofa.ark.common.util.StringUtils;

/**
* <p>
* BizOpsPodCoordinator class.
* </p>
*
* @author liuzhuoheng
* @since 2025/7/15
* @version 1.0.0
*/
public class BizOpsPodCoordinator {

/**
* bizIdentityLockMap
* key: bizIdentity, value: bizModelVersion
*/
private static final Map<String, String> bizIdentityLockMap = new ConcurrentHashMap<>();

/**
* <p>
* save.
* </p>
*
* @param bizIdentity a {@link java.lang.String} object
* @param bizModelVersion a {@link java.lang.String} object
* @return
*/
public static void save(String bizIdentity, String bizModelVersion) {
if (StringUtils.isEmpty(bizIdentity)) {
return;
}
if (StringUtils.isEmpty(bizModelVersion)) {
bizModelVersion = StringUtils.EMPTY_STRING;
}
bizIdentityLockMap.put(bizIdentity, bizModelVersion);
}

/**
* <p>
* remove.
* </p>
*
* @param bizIdentity a {@link java.lang.String} object
* @param bizModelVersion a {@link java.lang.String} object
* @return
*/
public static void remove(String bizIdentity, String bizModelVersion) {
if (StringUtils.isEmpty(bizIdentity)) {
return;
}
if (StringUtils.isEmpty(bizModelVersion)) {
bizIdentityLockMap.remove(bizIdentity);
return;
}
bizIdentityLockMap.remove(bizIdentity, bizModelVersion);
}

/**
* <p>
* canAccess.
* </p>
* 判断是否可以访问指定的业务模块,基于业务模块版本的协调机制
*
* @param bizIdentity 业务模块标识 (bizName:bizVersion)
* @param bizModelVersion 业务模块模型版本,用于命令协调和防止过期命令执行
* @return 是否允许访问该业务模块
*/
public static boolean canAccess(String bizIdentity, String bizModelVersion) {
// 判断逻辑说明:
// Case 1: bizModelVersion 为空 - 兼容性处理,允许访问(兼容旧版本 module-controller,arktcl,
// pod-not-exist 和 pod 紧急删除场景)
// Case 2: bizIdentityLockMap 中没有该 bizIdentity 的记录,允许访问(安装时不带
// BizModelVersion,卸载时带上 BizModelVersion)
// Case 3: bizIdentityLockMap 中的版本与当前请求的版本匹配 - 版本一致,确认卸载的是该 Biz,允许访问
// 只有当 bizModelVersion 不为空且存在 bizModelVersion 且不匹配时,才拒绝访问(防止旧的卸载命令执行)
return StringUtils.isEmpty(bizModelVersion)
|| StringUtils.isEmpty(bizIdentityLockMap.get(bizIdentity))
|| bizIdentityLockMap.get(bizIdentity).equals(bizModelVersion);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class ArkBizMeta extends InputMeta {
private String bizName;
private String bizVersion;
private String requestId;
private String bizModelVersion;
private boolean async;

/**
Expand Down Expand Up @@ -85,6 +86,24 @@ public void setRequestId(String requestId) {
this.requestId = requestId;
}

/**
* <p>Getter for the field <code>bizModelVersion</code>.</p>
*
* @return a {@link java.lang.String} object
*/
public String getBizModelVersion() {
return bizModelVersion;
}

/**
* <p>Setter for the field <code>bizModelVersion</code>.</p>
*
* @param bizModelVersion a {@link java.lang.String} object
*/
public void setBizModelVersion(String bizModelVersion) {
this.bizModelVersion = bizModelVersion;
}

/**
* <p>isAsync.</p>
*
Expand All @@ -102,4 +121,4 @@ public boolean isAsync() {
public void setAsync(boolean async) {
this.async = async;
}
}
}
Loading
Loading