Skip to content
Open
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
2 changes: 1 addition & 1 deletion conf/persistence.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<class>org.zstack.core.job.JobQueueEntryVO</class>
<class>org.zstack.core.config.GlobalConfigVO</class>
<class>org.zstack.core.eventlog.EventLogVO</class>
<class>org.zstack.core.plugin.PluginDriverVO</class>
<class>org.zstack.header.core.external.plugin.PluginDriverVO</class>
<class>org.zstack.resourceconfig.ResourceConfigVO</class>
<class>org.zstack.header.managementnode.ManagementNodeVO</class>
<class>org.zstack.header.managementnode.ManagementNodeContextVO</class>
Expand Down
70 changes: 45 additions & 25 deletions core/src/main/java/org/zstack/core/plugin/PluginManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.zstack.core.cloudbus.CloudBus;
import org.zstack.core.cloudbus.CloudBusCallBack;
import org.zstack.core.db.DatabaseFacade;
import org.zstack.core.db.GLock;
import org.zstack.core.db.Q;
import org.zstack.core.db.SQL;
import org.zstack.core.errorcode.ErrorFacade;
Expand Down Expand Up @@ -44,8 +45,10 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

Expand All @@ -57,6 +60,7 @@
*/
public class PluginManagerImpl extends AbstractService implements PluginManager {
private static final CLogger logger = Utils.getLogger(PluginManagerImpl.class);
private static final long PLUGIN_DRIVER_REGISTRATION_LOCK_TIMEOUT = TimeUnit.MINUTES.toSeconds(2);

@Autowired
private DatabaseFacade dbf;
Expand Down Expand Up @@ -135,42 +139,58 @@ protected void registerPluginAsSingleton(

verifyPluginProduct(pluginDriver);

persistPluginDriver(pluginDriver);

pluginInstances.put(pluginDriver.uuid(), pluginDriver);
List<PluginDriver> registeredPlugins = pluginRegisters.computeIfAbsent(
pluginDriverClz, k -> new ArrayList<>());
registeredPlugins.removeIf(registered -> Objects.equals(
registered.uuid(), pluginDriver.uuid()));
registeredPlugins.add(pluginDriver);

PluginDriverVO vo = dbf.findByUuid(pluginDriver.uuid(), PluginDriverVO.class);
if (vo == null) {
vo = new PluginDriverVO();
vo.setUuid(pluginDriver.uuid());
vo.setName(pluginDriver.name());
vo.setVendor(pluginDriver.vendor());
vo.setFeatures(JSONObjectUtil.toJsonString(pluginDriver.features()));
vo.setType(pluginDriver.type());
vo.setDescription(pluginDriver.description());
vo.setVersion(pluginDriver.version());
vo.setLicense(pluginDriver.license());
vo.setOptionTypes(JSONObjectUtil.toJsonString(pluginDriver.optionTypes()));
dbf.persist(vo);
} else {
vo.setName(pluginDriver.name());
vo.setVendor(pluginDriver.vendor());
vo.setFeatures(JSONObjectUtil.toJsonString(pluginDriver.features()));
vo.setType(pluginDriver.type());
vo.setDescription(pluginDriver.description());
vo.setVersion(pluginDriver.version());
vo.setLicense(pluginDriver.license());
vo.setOptionTypes(JSONObjectUtil.toJsonString(pluginDriver.optionTypes()));
dbf.update(vo);
}
} catch (Exception e) {
throw new CloudRuntimeException(e);
}
}

protected void persistPluginDriver(PluginDriver pluginDriver) {
GLock lock = createPluginDriverRegistrationLock(pluginDriver.uuid());
lock.lock();
try {
upsertPluginDriver(pluginDriver);
} finally {
lock.unlock();
}
}

protected GLock createPluginDriverRegistrationLock(String pluginUuid) {
String lockUuid = UUID.nameUUIDFromBytes(pluginUuid.getBytes(StandardCharsets.UTF_8)).toString();
return new GLock(String.format("plugin-driver-%s", lockUuid),
PLUGIN_DRIVER_REGISTRATION_LOCK_TIMEOUT, dbf);
}

protected void upsertPluginDriver(PluginDriver pluginDriver) {
PluginDriverVO vo = dbf.findByUuid(pluginDriver.uuid(), PluginDriverVO.class);
boolean newPlugin = vo == null;
if (newPlugin) {
vo = new PluginDriverVO();
vo.setUuid(pluginDriver.uuid());
}

vo.setName(pluginDriver.name());
vo.setVendor(pluginDriver.vendor());
vo.setFeatures(JSONObjectUtil.toJsonString(pluginDriver.features()));
vo.setType(pluginDriver.type());
vo.setDescription(pluginDriver.description());
vo.setVersion(pluginDriver.version());
vo.setLicense(pluginDriver.license());
vo.setOptionTypes(JSONObjectUtil.toJsonString(pluginDriver.optionTypes()));
if (newPlugin) {
dbf.persist(vo);
} else {
dbf.update(vo);
}
}

private void getPluginInterfaceSingletons(Class<? extends PluginDriver> abstractPluginClz) {
Platform.getReflections()
.getSubTypesOf(abstractPluginClz)
Expand Down