mirror of
https://gitee.com/jmix/cuba.git
synced 2024-11-30 18:27:56 +08:00
PL-6897 Remove old license restrictions
This commit is contained in:
parent
799d2e6db1
commit
d5a39d05d5
20
build.gradle
20
build.gradle
@ -152,7 +152,6 @@ configure([sharedLibModule, globalModule, coreModule, clientModule, guiModule,
|
||||
|
||||
task sourceJar(type: Jar) {
|
||||
from file('src')
|
||||
exclude "com/haulmont/cuba/security/app/UserSessions.java"
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
@ -208,7 +207,6 @@ configure(webToolkitModule) {
|
||||
|
||||
task sourceJar(type: Jar) {
|
||||
from file('src')
|
||||
exclude "com/haulmont/cuba/security/app/UserSessions.java"
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
@ -304,24 +302,6 @@ configure(coreModule) {
|
||||
testRuntime(postgres)
|
||||
}
|
||||
|
||||
task recompileNoDebug(type: JavaCompile) {
|
||||
source = sourceSets.main.java
|
||||
classpath = sourceSets.main.compileClasspath
|
||||
destinationDir = new File(buildDir, 'nodebug-classes')
|
||||
options.debug = false
|
||||
}
|
||||
|
||||
jar {
|
||||
exclude { details ->
|
||||
return details.file == new File("${sourceSets.main.output.classesDir}/com/haulmont/cuba/security/app/UserSessions.class")
|
||||
}
|
||||
from("$buildDir/nodebug-classes") {
|
||||
include "com/haulmont/cuba/security/app/UserSessions.class"
|
||||
}
|
||||
}
|
||||
|
||||
jar.dependsOn(recompileNoDebug)
|
||||
|
||||
test {
|
||||
scanForTestClasses = false
|
||||
includes = ['**/*Test.class']
|
||||
|
@ -125,13 +125,6 @@ public interface ServerConfig extends Config {
|
||||
int getDefaultQueryTimeoutSec();
|
||||
void setDefaultQueryTimeoutSec(int timeout);
|
||||
|
||||
/**
|
||||
* @return Path to the license file
|
||||
*/
|
||||
@Property("cuba.licensePath")
|
||||
@Default("/cuba.license")
|
||||
String getLicensePath();
|
||||
|
||||
/**
|
||||
* Indicates that a new user session created on login should be sent to the cluster synchronously.
|
||||
*/
|
||||
|
@ -16,21 +16,32 @@
|
||||
*/
|
||||
package com.haulmont.cuba.core.app;
|
||||
|
||||
import com.haulmont.bali.db.QueryRunner;
|
||||
import com.haulmont.cuba.core.Persistence;
|
||||
import com.haulmont.cuba.core.global.Configuration;
|
||||
import com.haulmont.cuba.core.global.GlobalConfig;
|
||||
import com.haulmont.cuba.core.global.TimeSource;
|
||||
import com.haulmont.cuba.core.global.UuidSource;
|
||||
import com.haulmont.cuba.core.sys.AppContext;
|
||||
import com.haulmont.cuba.core.sys.persistence.DbTypeConverter;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.Types;
|
||||
import java.util.Date;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*/
|
||||
@Component(ServerInfoAPI.NAME)
|
||||
public class ServerInfo implements ServerInfoAPI {
|
||||
public class ServerInfo implements ServerInfoAPI, AppContext.Listener {
|
||||
|
||||
public static final String CUBA_RELEASE_NUMBER_PATH = "/com/haulmont/cuba/core/global/release.number";
|
||||
public static final String CUBA_RELEASE_TIMESTAMP_PATH = "/com/haulmont/cuba/core/global/release.timestamp";
|
||||
@ -44,6 +55,21 @@ public class ServerInfo implements ServerInfoAPI {
|
||||
|
||||
protected volatile String serverId;
|
||||
|
||||
private GlobalConfig globalConfig;
|
||||
|
||||
@Inject
|
||||
protected TimeSource timeSource;
|
||||
|
||||
@Inject
|
||||
protected Persistence persistence;
|
||||
|
||||
@Inject
|
||||
private UuidSource uuidSource;
|
||||
|
||||
public ServerInfo() {
|
||||
AppContext.addListener(this);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setConfiguration(Configuration configuration) {
|
||||
this.configuration = configuration;
|
||||
@ -65,6 +91,8 @@ public class ServerInfo implements ServerInfoAPI {
|
||||
log.warn("Unable to read release timestamp", e);
|
||||
}
|
||||
}
|
||||
|
||||
globalConfig = configuration.getConfig(GlobalConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -85,4 +113,78 @@ public class ServerInfo implements ServerInfoAPI {
|
||||
}
|
||||
return serverId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applicationStarted() {
|
||||
if (!globalConfig.getTestMode()) {
|
||||
Timer timer = new Timer(true);
|
||||
timer.schedule(
|
||||
new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (AppContext.isStarted()) {
|
||||
updateCurrentServer();
|
||||
}
|
||||
}
|
||||
},
|
||||
30000,
|
||||
60000
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applicationStopped() {
|
||||
try {
|
||||
log.trace("Updating server information in the database");
|
||||
|
||||
DbTypeConverter types = persistence.getDbTypeConverter();
|
||||
Object tsObj = types.getSqlObject(timeSource.currentTimestamp());
|
||||
int tsType = types.getSqlType(Date.class);
|
||||
Object falseObj = types.getSqlObject(Boolean.FALSE);
|
||||
int boolType = types.getSqlType(Boolean.class);
|
||||
|
||||
QueryRunner runner = new QueryRunner(persistence.getDataSource());
|
||||
runner.update(
|
||||
"update SYS_SERVER set UPDATE_TS = ?, IS_RUNNING = ? where NAME = ?",
|
||||
new Object[]{tsObj, falseObj, getServerId()},
|
||||
new int[]{tsType, boolType, Types.VARCHAR}
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.error("Unable to update SYS_SERVER: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
void updateCurrentServer() {
|
||||
try {
|
||||
log.trace("Updating server information in the database");
|
||||
String serverId = getServerId();
|
||||
|
||||
DbTypeConverter types = persistence.getDbTypeConverter();
|
||||
Object tsObj = types.getSqlObject(timeSource.currentTimestamp());
|
||||
int tsType = types.getSqlType(Date.class);
|
||||
Object trueObj = types.getSqlObject(Boolean.TRUE);
|
||||
int boolType = types.getSqlType(Boolean.class);
|
||||
|
||||
QueryRunner runner = new QueryRunner(persistence.getDataSource());
|
||||
|
||||
int updated = runner.update(
|
||||
"update SYS_SERVER set UPDATE_TS = ?, IS_RUNNING = ? where NAME = ?",
|
||||
new Object[]{tsObj, trueObj, serverId},
|
||||
new int[]{tsType, boolType, Types.VARCHAR}
|
||||
);
|
||||
if (updated == 0) {
|
||||
Object id = types.getSqlObject(uuidSource.createUuid());
|
||||
int idType = types.getSqlType(UUID.class);
|
||||
runner.update(
|
||||
"insert into SYS_SERVER (ID, CREATE_TS, UPDATE_TS, NAME, IS_RUNNING) " +
|
||||
"values (?, ?, ?, ?, ?)",
|
||||
new Object[]{id, tsObj, tsObj, serverId, trueObj},
|
||||
new int[]{idType, tsType, tsType, Types.VARCHAR, boolType}
|
||||
);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unable to update SYS_SERVER: " + e);
|
||||
}
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ package com.haulmont.cuba.core.app;
|
||||
|
||||
/**
|
||||
* Interface to provide basic information about the middleware.
|
||||
*
|
||||
*/
|
||||
public interface ServerInfoAPI {
|
||||
|
||||
|
@ -102,11 +102,6 @@ public class UserSessionServiceBean implements UserSessionService {
|
||||
return userSessions.getUserSessionInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<String, Object> getLicenseInfo() {
|
||||
return userSessions.getLicenseInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void killSession(UUID id) {
|
||||
userSessions.killSession(id);
|
||||
|
@ -16,55 +16,31 @@
|
||||
*/
|
||||
package com.haulmont.cuba.security.app;
|
||||
|
||||
import com.haulmont.bali.db.QueryRunner;
|
||||
import com.haulmont.bali.db.ResultSetHandler;
|
||||
import com.haulmont.bali.util.Dom4j;
|
||||
import com.haulmont.chile.core.model.MetaModel;
|
||||
import com.haulmont.cuba.core.Persistence;
|
||||
import com.haulmont.cuba.core.app.ClusterListener;
|
||||
import com.haulmont.cuba.core.app.ClusterManagerAPI;
|
||||
import com.haulmont.cuba.core.app.ServerConfig;
|
||||
import com.haulmont.cuba.core.app.ServerInfoAPI;
|
||||
import com.haulmont.cuba.core.global.*;
|
||||
import com.haulmont.cuba.core.global.Configuration;
|
||||
import com.haulmont.cuba.core.global.Metadata;
|
||||
import com.haulmont.cuba.core.global.TimeSource;
|
||||
import com.haulmont.cuba.core.sys.AppContext;
|
||||
import com.haulmont.cuba.core.sys.persistence.DbTypeConverter;
|
||||
import com.haulmont.cuba.security.entity.Role;
|
||||
import com.haulmont.cuba.security.entity.User;
|
||||
import com.haulmont.cuba.security.entity.UserSessionEntity;
|
||||
import com.haulmont.cuba.security.global.UserSession;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.Element;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* User sessions distributed cache.
|
||||
*
|
||||
*/
|
||||
@Component(UserSessionsAPI.NAME)
|
||||
public final class UserSessions implements UserSessionsAPI, AppContext.Listener {
|
||||
|
||||
public static final String NOT_RESTRICTED = "Not restricted";
|
||||
public final class UserSessions implements UserSessionsAPI {
|
||||
|
||||
static class UserSessionInfo implements Serializable {
|
||||
private static final long serialVersionUID = -4834267718111570841L;
|
||||
@ -95,29 +71,11 @@ public final class UserSessions implements UserSessionsAPI, AppContext.Listener
|
||||
|
||||
private UserSession NO_USER_SESSION;
|
||||
|
||||
private GlobalConfig globalConfig;
|
||||
|
||||
private ServerConfig serverConfig;
|
||||
|
||||
private byte[] bytes;
|
||||
|
||||
private int count;
|
||||
|
||||
@Inject
|
||||
private TimeSource timeSource;
|
||||
|
||||
@Inject
|
||||
private UuidSource uuidSource;
|
||||
|
||||
@Inject
|
||||
private ServerInfoAPI serverInfo;
|
||||
|
||||
@Inject
|
||||
private Persistence persistence;
|
||||
|
||||
@Inject
|
||||
private Resources resources;
|
||||
|
||||
@Inject
|
||||
private Metadata metadata;
|
||||
|
||||
@ -132,12 +90,10 @@ public final class UserSessions implements UserSessionsAPI, AppContext.Listener
|
||||
return AppContext.NO_USER_CONTEXT.getSessionId();
|
||||
}
|
||||
};
|
||||
AppContext.addListener(this);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setConfiguration(Configuration configuration) {
|
||||
globalConfig = configuration.getConfig(GlobalConfig.class);
|
||||
serverConfig = configuration.getConfig(ServerConfig.class);
|
||||
setExpirationTimeoutSec(serverConfig.getUserSessionExpirationTimeoutSec());
|
||||
}
|
||||
@ -201,197 +157,6 @@ public final class UserSessions implements UserSessionsAPI, AppContext.Listener
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applicationStarted() {
|
||||
|
||||
String encodedStr = resources.getResourceAsString(serverConfig.getLicensePath());
|
||||
if (encodedStr == null) {
|
||||
log.error("\n======================================================"
|
||||
+ "\nInvalid license path: " + serverConfig.getLicensePath()
|
||||
+ "\n======================================================");
|
||||
} else {
|
||||
Object[] objects;
|
||||
try {
|
||||
bytes = Base64.decodeBase64(encodedStr);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
objects = decode();
|
||||
if (objects != null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("\n======================================================");
|
||||
sb.append("\nCUBA platform license");
|
||||
sb.append("\nType: ").append(objects[0]);
|
||||
sb.append("\nLicense ID: ").append(objects[1]);
|
||||
sb.append("\nLicensed to: ").append(objects[2]);
|
||||
sb.append("\nApplication: ").append(objects[3]);
|
||||
sb.append("\nValid for CUBA platform releases up to: ").append(objects[4]);
|
||||
sb.append("\nMaximum number of sessions: ").append(((int) objects[5]) == 0 ? NOT_RESTRICTED : objects[5]);
|
||||
sb.append("\nMaximum number of entities: ").append(((int) objects[6]) == 0 ? NOT_RESTRICTED : objects[6]);
|
||||
sb.append("\n======================================================");
|
||||
log.warn(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (!globalConfig.getTestMode()) {
|
||||
Timer timer = new Timer(true);
|
||||
timer.schedule(
|
||||
new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (AppContext.isStarted()) {
|
||||
count = updateCurrentSessions(cache.values());
|
||||
}
|
||||
}
|
||||
},
|
||||
20000,
|
||||
10000
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applicationStopped() {
|
||||
try {
|
||||
String serverId = serverInfo.getServerId();
|
||||
long now = timeSource.currentTimeMillis();
|
||||
|
||||
DbTypeConverter types = persistence.getDbTypeConverter();
|
||||
Object tsObj = types.getSqlObject(new Date(now));
|
||||
int tsType = types.getSqlType(Date.class);
|
||||
Object falseObj = types.getSqlObject(Boolean.FALSE);
|
||||
int boolType = types.getSqlType(Boolean.class);
|
||||
|
||||
QueryRunner runner = new QueryRunner(persistence.getDataSource());
|
||||
runner.update(
|
||||
"update SYS_SERVER set UPDATE_TS = ?, IS_RUNNING = ?, DATA = null where NAME = ?",
|
||||
new Object[]{tsObj, falseObj, serverId},
|
||||
new int[]{tsType, boolType, Types.VARCHAR}
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.error("Unable to update SYS_SERVER: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private Object[] decode() {
|
||||
try {
|
||||
BigInteger modulus = new BigInteger("18067575663987735326841242779464849963427753383058608867564135320738629147323691302736061591062052549416513716629888492493056820982621037983191693191253192501503395852012311582921940563059939819291206980413052487032632214809671460979641654935753772670912438930755064425437054092209398837918235045229999194411886527048670166121407791756890867519091491607028477744091266213650133388651959054937201410008848221420087836750419721605315470836864588770539438076268570475092652895671550938980095793057202388488186533973398706509535952619833352266143112184736108225487400680111445272274042274164391489296561006468854335469461");
|
||||
BigInteger exponent = new BigInteger("65537");
|
||||
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PublicKey publicKey = keyFactory.generatePublic(keySpec);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicKey);
|
||||
byte[] decoded = cipher.doFinal(bytes);
|
||||
String str = new String(decoded, StandardCharsets.UTF_8);
|
||||
String[] split = str.split("\\^");
|
||||
|
||||
Object[] arr = new Object[7];
|
||||
if (split.length == 7) {
|
||||
arr[0] = split[0].trim(); // type
|
||||
arr[1] = split[1].trim(); // id
|
||||
arr[2] = split[2].trim(); // to
|
||||
arr[3] = split[3].trim(); // app
|
||||
arr[4] = split[4].trim(); // platform date
|
||||
arr[5] = Integer.valueOf(split[5].trim()); // sessions
|
||||
arr[6] = Integer.valueOf(split[6].trim()); // entities
|
||||
} else if (split.length == 3) {
|
||||
arr[0] = "Commercial"; // type
|
||||
arr[1] = "1400001"; // id
|
||||
arr[2] = split[1].trim(); // to
|
||||
arr[3] = NOT_RESTRICTED; // app
|
||||
arr[4] = NOT_RESTRICTED; // platform date
|
||||
arr[5] = Integer.valueOf(split[2].trim()); // sessions
|
||||
arr[6] = 0; // entities
|
||||
} else
|
||||
throw new RuntimeException();
|
||||
|
||||
if (!arr[3].equals(NOT_RESTRICTED)) {
|
||||
boolean found = false;
|
||||
String config = AppContext.getProperty("cuba.metadataConfig");
|
||||
String[] files = config.split("\\s");
|
||||
String file = files[files.length - 1];
|
||||
InputStream stream = resources.getResourceAsStream(file);
|
||||
if (stream == null) {
|
||||
log.error("Cannot load '" + file + "' to check application name");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
try {
|
||||
Document document = Dom4j.readDocument(stream);
|
||||
Element root = document.getRootElement();
|
||||
for (Element element : (List<Element>) root.elements("metadata-model")) {
|
||||
if (arr[3].equals(element.attributeValue("root-package"))) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(stream);
|
||||
}
|
||||
if (!found) {
|
||||
log.error("\n======================================================"
|
||||
+ "\nInvalid license file at " + serverConfig.getLicensePath()
|
||||
+ "\napplication name mismatch"
|
||||
+ "\n======================================================");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!arr[4].equals(NOT_RESTRICTED)) {
|
||||
InputStream stream = getClass().getResourceAsStream("/com/haulmont/cuba/core/global/release.timestamp");
|
||||
if (stream == null) {
|
||||
log.error("Cannot load platform release timestamp");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
String relStr = IOUtils.toString(stream);
|
||||
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date relDate = fmt.parse(relStr.substring(0, 10));
|
||||
Date licDate = fmt.parse((String) arr[4]);
|
||||
if (relDate.after(licDate)) {
|
||||
log.error("\n======================================================"
|
||||
+ "\nInvalid license file at " + serverConfig.getLicensePath()
|
||||
+ "\nunsupported platform release (licensed for releases"
|
||||
+ "\nup to " + arr[4] + ", current release: " + relStr.substring(0, 10) + ")"
|
||||
+ "\n======================================================");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if ((int)arr[6] != 0) {
|
||||
int count = 0;
|
||||
for (MetaModel metaModel : metadata.getSession().getModels()) {
|
||||
String name = metaModel.getName();
|
||||
if (!name.equals("com.haulmont.cuba")
|
||||
&& !name.equals("com.haulmont.reports")
|
||||
&& !name.equals("com.haulmont.workflow")
|
||||
&& !name.equals("com.haulmont.fts")
|
||||
&& !name.equals("com.haulmont.ccpayments")
|
||||
&& !name.equals("com.haulmont.bpmn"))
|
||||
{
|
||||
count += metaModel.getClasses().size();
|
||||
}
|
||||
}
|
||||
if (count > (int)arr[6]) {
|
||||
log.error("\n======================================================"
|
||||
+ "\nInvalid license file at " + serverConfig.getLicensePath()
|
||||
+ "\nmaximum number of entities exceeded "
|
||||
+ "\n(licensed: " + arr[6] + ", actual: " + count + ")"
|
||||
+ "\n======================================================");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("\n======================================================"
|
||||
+ "\nInvalid license data at " + serverConfig.getLicensePath()
|
||||
+ ("on".equals(System.getProperty("cuba.lcnsng.debug")) ? "\n" + ExceptionUtils.getFullStackTrace(e) : "")
|
||||
+ "\n======================================================");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(UserSession session) {
|
||||
UserSessionInfo usi = new UserSessionInfo(session, timeSource.currentTimeMillis());
|
||||
@ -402,16 +167,6 @@ public final class UserSessions implements UserSessionsAPI, AppContext.Listener
|
||||
else
|
||||
clusterManager.send(usi);
|
||||
}
|
||||
Object[] objects = decode();
|
||||
if (objects != null) {
|
||||
int licensed = (int) objects[5];
|
||||
if (licensed != 0 && count > licensed) {
|
||||
LoggerFactory.getLogger("com.haulmont.cuba.security.app.LoginWorkerBean").warn(
|
||||
String.format("Active sessions: %d, licensed: %d", count, licensed));
|
||||
}
|
||||
} else {
|
||||
LoggerFactory.getLogger("com.haulmont.cuba.security.app.LoginWorkerBean").error("Invalid license data");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -469,21 +224,6 @@ public final class UserSessions implements UserSessionsAPI, AppContext.Listener
|
||||
return sessionInfoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getLicenseInfo() {
|
||||
Object[] objects = decode();
|
||||
Map<String, Object> info = new LinkedHashMap<>();
|
||||
info.put("licenseType", objects != null ? objects[0] : "invalid data");
|
||||
info.put("licenseId", objects != null ? objects[1] : "invalid data");
|
||||
info.put("licensedTo", objects != null ? objects[2] : "invalid data");
|
||||
info.put("rootPackage", objects != null ? objects[3] : "invalid data");
|
||||
info.put("licensedReleaseDate", objects != null ? objects[4] : "invalid data");
|
||||
info.put("licensedSessions", objects != null ? objects[5] : -1);
|
||||
info.put("licensedEntities", objects != null ? objects[6] : -1);
|
||||
info.put("activeSessions", count);
|
||||
return info;
|
||||
}
|
||||
|
||||
private UserSessionEntity createUserSessionEntity(UserSession session, long since, long lastUsedTs) {
|
||||
UserSessionEntity use = metadata.create(UserSessionEntity.class);
|
||||
use.setId(session.getId());
|
||||
@ -528,66 +268,4 @@ public final class UserSessions implements UserSessionsAPI, AppContext.Listener
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int updateCurrentSessions(Collection<UserSessionInfo> userSessionInfo) {
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (UserSessionInfo info : userSessionInfo) {
|
||||
sb.append(info.session.getId()).append("\n");
|
||||
}
|
||||
|
||||
String serverId = serverInfo.getServerId();
|
||||
long now = timeSource.currentTimeMillis();
|
||||
|
||||
DbTypeConverter types = persistence.getDbTypeConverter();
|
||||
Object tsObj = types.getSqlObject(new Date(now));
|
||||
int tsType = types.getSqlType(Date.class);
|
||||
Object trueObj = types.getSqlObject(Boolean.TRUE);
|
||||
int boolType = types.getSqlType(Boolean.class);
|
||||
|
||||
QueryRunner runner = new QueryRunner(persistence.getDataSource());
|
||||
|
||||
int updated = runner.update(
|
||||
"update SYS_SERVER set UPDATE_TS = ?, IS_RUNNING = ?, DATA = ? where NAME = ?",
|
||||
new Object[]{tsObj, trueObj, sb.toString(), serverId},
|
||||
new int[]{tsType, boolType, Types.VARCHAR, Types.VARCHAR}
|
||||
);
|
||||
if (updated == 0) {
|
||||
Object id = types.getSqlObject(uuidSource.createUuid());
|
||||
int idType = types.getSqlType(UUID.class);
|
||||
runner.update(
|
||||
"insert into SYS_SERVER (ID, CREATE_TS, UPDATE_TS, NAME, IS_RUNNING, DATA) " +
|
||||
"values (?, ?, ?, ?, ?, ?)",
|
||||
new Object[]{id, tsObj, tsObj, serverId, trueObj, sb.toString()},
|
||||
new int[]{idType, tsType, tsType, Types.VARCHAR, boolType, Types.VARCHAR}
|
||||
);
|
||||
}
|
||||
return runner.query(
|
||||
"select DATA from SYS_SERVER where IS_RUNNING = ? and UPDATE_TS > ?",
|
||||
new Object[]{trueObj, types.getSqlObject(new Date(now - 30000))},
|
||||
new int[] {boolType, tsType},
|
||||
new ResultSetHandler<Integer>() {
|
||||
@Override
|
||||
public Integer handle(ResultSet rs) throws SQLException {
|
||||
Set<UUID> set = new HashSet<>();
|
||||
while (rs.next()) {
|
||||
String data = rs.getString(1);
|
||||
if (data != null) {
|
||||
String[] strings = data.split("\\s");
|
||||
for (String string : strings) {
|
||||
if (!StringUtils.isEmpty(string)) {
|
||||
set.add(UuidProvider.fromString(string));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return set.size();
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.error("Unable to update SYS_SERVER: " + e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
@ -20,12 +20,10 @@ import com.haulmont.cuba.security.entity.UserSessionEntity;
|
||||
import com.haulmont.cuba.security.global.UserSession;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* User sessions distributed cache API.
|
||||
*
|
||||
*/
|
||||
public interface UserSessionsAPI {
|
||||
|
||||
@ -54,8 +52,6 @@ public interface UserSessionsAPI {
|
||||
*/
|
||||
Collection<UserSessionEntity> getUserSessionInfo();
|
||||
|
||||
Map<String, Object> getLicenseInfo();
|
||||
|
||||
/**
|
||||
* Immediately remove a sessions from cache.
|
||||
* @param id session id
|
||||
|
@ -92,11 +92,6 @@ public interface UserSessionService {
|
||||
*/
|
||||
Collection<UserSessionEntity> getUserSessionInfo();
|
||||
|
||||
/**
|
||||
* @return license information
|
||||
*/
|
||||
Map<String, Object> getLicenseInfo();
|
||||
|
||||
/**
|
||||
* Disconnect a session. Returns silently if there is no active session with the specified ID.
|
||||
* @param id an active session identifier
|
||||
|
@ -25,9 +25,6 @@
|
||||
|
||||
<layout>
|
||||
<tabSheet width="100%" height="100%">
|
||||
<tab id="infoTab" caption="msg://info" margin="true" spacing="true">
|
||||
<frame id="license" screen="licenseFrame" width="100%" height="100%"/>
|
||||
</tab>
|
||||
<tab id="creditsTab" caption="msg://credits" margin="true">
|
||||
<frame id="credits" screen="creditsFrame" width="100%" height="100%"/>
|
||||
</tab>
|
||||
|
@ -19,7 +19,6 @@ package com.haulmont.cuba.gui.app.core.license;
|
||||
|
||||
import com.haulmont.cuba.gui.components.AbstractFrame;
|
||||
import com.haulmont.cuba.gui.components.TextArea;
|
||||
import com.haulmont.cuba.security.app.UserSessionService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Map;
|
||||
@ -28,26 +27,12 @@ import java.util.Map;
|
||||
*/
|
||||
public class LicenseFrame extends AbstractFrame {
|
||||
|
||||
@Inject
|
||||
private UserSessionService uss;
|
||||
@Inject
|
||||
private TextArea licenseTxtField;
|
||||
|
||||
@Override
|
||||
public void init(Map<String, Object> params) {
|
||||
Map<String, Object> info = uss.getLicenseInfo();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Map.Entry<String, Object> entry : info.entrySet()) {
|
||||
Object val = entry.getValue();
|
||||
if (entry.getKey().equals("licensedSessions") || entry.getKey().equals("licensedEntities")) {
|
||||
val = ((val instanceof Integer) && ((Integer) val == 0)) ? "Not restricted" : val;
|
||||
}
|
||||
sb.append(getMessage(entry.getKey())).append(": ").append(val).append("\n");
|
||||
}
|
||||
|
||||
licenseTxtField.setValue(sb.toString());
|
||||
licenseTxtField.setValue("Obsolete");
|
||||
licenseTxtField.setEditable(false);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -16,11 +16,3 @@
|
||||
#
|
||||
|
||||
licenseTitle = CUBA platform license
|
||||
licenseType = License Type
|
||||
licenseId = License ID
|
||||
licensedTo = Licensed To
|
||||
rootPackage = Root package
|
||||
licensedReleaseDate = Valid for CUBA platform releases up to
|
||||
licensedSessions = Maximum number of sessions
|
||||
licensedEntities = Maximum number of entities
|
||||
activeSessions = Current number of sessions
|
||||
|
@ -54,9 +54,6 @@ public class SessionBrowser extends AbstractLookup {
|
||||
@Inject
|
||||
protected Label lastUpdateTsLab;
|
||||
|
||||
@Inject
|
||||
protected Label sessionsInfo;
|
||||
|
||||
@Inject
|
||||
protected TextField userLogin;
|
||||
|
||||
@ -84,21 +81,6 @@ public class SessionBrowser extends AbstractLookup {
|
||||
sessionsDs.addCollectionChangeListener(e -> {
|
||||
String time = Datatypes.getNN(Date.class).format(sessionsDs.getUpdateTs(), userSessionSource.getLocale());
|
||||
lastUpdateTsLab.setValue(time);
|
||||
|
||||
Map<String, Object> info = uss.getLicenseInfo();
|
||||
Integer licensed = (Integer) info.get("licensedSessions");
|
||||
Integer active = (Integer) info.get("activeSessions");
|
||||
if (licensed == 0) {
|
||||
sessionsInfo.setVisible(false);
|
||||
} else {
|
||||
sessionsInfo.setValue(messages.formatMessage(getMessagesPack(), "sessionsInfo",
|
||||
info.get("activeSessions"), info.get("licensedSessions")));
|
||||
if (active > licensed) {
|
||||
sessionsInfo.setStyleName("h2-red");
|
||||
} else {
|
||||
sessionsInfo.setStyleName(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
addAction(refreshAction);
|
||||
|
@ -34,7 +34,7 @@
|
||||
<assign name="filterFieldWidth" value="theme://cuba.gui.session-browse.filterField.width"/>
|
||||
|
||||
<layout expand="sessionsTable" spacing="true">
|
||||
<hbox id="filterHBox" spacing="true" expand="spacer" width="100%">
|
||||
<hbox id="filterHBox" spacing="true" width="100%">
|
||||
<groupBox id="filterGroupBox" caption="msg://filter" orientation="horizontal" spacing="true" width="AUTO">
|
||||
<grid id="filterGrid" spacing="true">
|
||||
<columns count="4"/>
|
||||
@ -56,8 +56,6 @@
|
||||
|
||||
<button id="clearButton" caption="msg://clear" align="BOTTOM_RIGHT" invoke="clearTextFields"/>
|
||||
</groupBox>
|
||||
<label id="spacer"/>
|
||||
<label id="sessionsInfo" align="TOP_RIGHT"/>
|
||||
</hbox>
|
||||
<groupTable id="sessionsTable" multiselect="true" width="100%">
|
||||
<actions>
|
||||
|
@ -31,7 +31,6 @@ import com.haulmont.cuba.gui.components.mainwindow.UserIndicator;
|
||||
import com.haulmont.cuba.gui.config.WindowConfig;
|
||||
import com.haulmont.cuba.gui.config.WindowInfo;
|
||||
import com.haulmont.cuba.gui.theme.ThemeConstantsRepository;
|
||||
import com.haulmont.cuba.security.app.UserSessionService;
|
||||
import com.haulmont.cuba.web.app.UserSettingsTools;
|
||||
import com.haulmont.cuba.web.gui.components.mainwindow.WebAppWorkArea;
|
||||
import com.haulmont.cuba.web.toolkit.ui.*;
|
||||
@ -149,8 +148,6 @@ public class AppWindow extends UIView implements CubaHistoryControl.HistoryBackH
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
checkSessions();
|
||||
|
||||
updateClientSystemMessages();
|
||||
|
||||
beforeInitLayout();
|
||||
@ -230,22 +227,6 @@ public class AppWindow extends UIView implements CubaHistoryControl.HistoryBackH
|
||||
public void onHistoryBackPerformed() {
|
||||
}
|
||||
|
||||
private void checkSessions() {
|
||||
UserSessionService userSessionService = AppBeans.get(UserSessionService.NAME);
|
||||
Map<String, Object> info = userSessionService.getLicenseInfo();
|
||||
Integer licensed = (Integer) info.get("licensedSessions");
|
||||
if (licensed < 0) {
|
||||
Notification.show("Invalid CUBA platform license. See server log for details.",
|
||||
Notification.Type.ERROR_MESSAGE);
|
||||
} else {
|
||||
Integer active = (Integer) info.get("activeSessions");
|
||||
if (licensed != 0 && active > licensed) {
|
||||
Notification.show("Number of licensed sessions exceeded", "active: " + active + ", licensed: " + licensed,
|
||||
Notification.Type.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return getAppCaption();
|
||||
|
Loading…
Reference in New Issue
Block a user