Changeset 7950


Ignore:
Timestamp:
May 10, 2021, 2:02:56 PM (7 months ago)
Author:
Nicklas Nordborg
Message:

References #2250: Named transactions

Implemented a concept of "current client" since it is possible to access a given SessionControl with a different client application in Application.getSessionControl() than the client that created it. This "current client" information lives in a thread-local variable since it is possible that multiple threads for multiple client application is using the same SessionControl at once. The "current client" is used in the change history logging.

Location:
trunk/src/core/net/sf/basedb/core
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/net/sf/basedb/core/Application.java

    r7926 r7950  
    992992    }
    993993    sc.updateLastAccess();
     994   
     995    sc.setCurrentClient(externalClientId);
     996   
    994997    return sc;
    995998  }
  • trunk/src/core/net/sf/basedb/core/SessionControl.java

    r7946 r7950  
    104104
    105105  /**
    106     The id of the {@link ClientData}. 0 = no client
    107   */
    108   private final int clientId;
    109   private final String clientName;
    110  
    111   /**
    112     The external id of the {@link ClientData}. null = no client
    113   */
    114   private final String externalClientId;
    115 
     106    Information about the {@link ClientData} that created this SessionControl.
     107    null = no client
     108  */
     109  private final ClientInfo client;
     110 
     111  /**
     112    Information about the current {@link ClientData} that checked out
     113    this SessionControl. This is a ThreadLocal.
     114   */
     115  private final ThreadLocal<ClientInfo> currentClient;
     116 
    116117  /**
    117118    The remote IP.
     
    184185  {
    185186    this.id = id;
    186     this.clientId = parent.clientId;
    187     this.clientName = parent.clientName;
    188     this.externalClientId = parent.externalClientId;
     187    this.client = parent.client;
     188    this.currentClient = parent.currentClient;
    189189    this.remoteId = parent.remoteId;
    190190    this.dbControlCache = Collections.synchronizedMap(new WeakHashMap<DbControl,String>());
     
    218218  {
    219219    this.id = id;
    220     this.externalClientId = externalClientId;
    221220    this.remoteId = remoteId;
    222221    this.dbControlCache = Collections.synchronizedMap(new WeakHashMap<DbControl,String>());
     
    224223    this.allowedClients = Collections.synchronizedMap(new HashMap<String, Boolean>());
    225224    int tempClientId = 0;
    226     String tempClientName = null;
     225    ClientInfo tmpClient = null;
    227226    if (externalClientId != null)
    228227    {
     
    246245        if (clientData != null)
    247246        {
    248           tempClientId = clientData.getId();
    249           tempClientName = clientData.getName();
     247          tmpClient = new ClientInfo(clientData.getId(), externalClientId, clientData.getName());
     248          //tempClientId = clientData.getId();
     249          //tempClientName = clientData.getName();
    250250          // load default settings for client application
    251251          clientDefaultSettings = loadClientDefaultSettings(session, tempClientId);
     
    262262      }
    263263    }
    264     this.clientId = tempClientId;
    265     this.clientName = tempClientName;
     264    this.client = tmpClient;
     265    this.currentClient = new ThreadLocal<>();
     266    currentClient.set(client);
    266267    updateLastAccess();
    267268  }
     
    322323 
    323324  /**
    324     Get the id of the <code>Client</code> application in use. Use
    325     {@link Client#getById(DbControl, int)} to get the {@link Client} object.
    326     @return Client id as an int.
     325    Get the id of the <code>Client</code> application that created this SessionControl.
     326    Use {@link Client#getById(DbControl, int)} to get the {@link Client} object.
     327    @return Client id as an int or 0 if not known.
    327328  */
    328329  public int getClientId()
    329330  {
    330331    updateLastAccess();
    331     return clientId;
    332   }
    333 
    334   /**
    335     Get the name of the <code>Client</code> application in use.
     332    return client == null ? 0 : client.id;
     333  }
     334
     335  /**
     336    Get the id of the <code>Client</code> application that checked out this
     337    SessionControl from {@link Application#getSessionControl(String, String, String, boolean)}.
     338    @return Client id as an int or 0 if not known.
     339    @since 3.19
     340  */
     341  public int getCurrentClientId()
     342  {
     343    return currentClient.get() == null ? getClientId() : currentClient.get().id;
     344  }
     345 
     346  /**
     347    Get the name of the <code>Client</code> application that created this SessionControl.
    336348    @return The client name, or null if no client was specified
    337349    @since 3.19
     
    340352  {
    341353    updateLastAccess();
    342     return clientName;
    343   }
    344  
    345   /**
    346     Get the external id of the <code>Client</code> application in use.
     354    return client == null ? null : client.name;
     355  }
     356 
     357  /**
     358    Get the name of the <code>Client</code> application that checked out this
     359    SessionControl from {@link Application#getSessionControl(String, String, String, boolean)}.
     360    @return The client name, or null if no client was specified
     361    @since 3.19
     362  */
     363  public String getCurrentClientName()
     364  {
     365    return currentClient.get() == null ? getClientName() : currentClient.get().name;
     366  }
     367
     368 
     369  /**
     370    Get the external id of the <code>Client</code> application that created this SessionControl.
    347371    @return A java.lang.String object.
    348372    @see #getClientId()
     
    351375  {
    352376    updateLastAccess();
    353     return externalClientId;
     377    return client == null ? null : client.externalId;
     378  }
     379 
     380  /**
     381    Get the external id of the <code>Client</code> application that checked out this
     382    SessionControl from {@link Application#getSessionControl(String, String, String, boolean)}.
     383    @return The client external id, or null if no client was specified
     384    @since 3.19
     385  */
     386  public String getCurrentExternalClientId()
     387  {
     388    return currentClient.get() == null ? getExternalClientId() : currentClient.get().externalId;
     389  }
     390 
     391  void setCurrentClient(String externalId)
     392  {
     393    ClientData cc = getClientWithExternalId(externalId);
     394    currentClient.set(cc == null ? null : new ClientInfo(cc.getId(), cc.getExternalId(), cc.getName()));
    354395  }
    355396 
     
    475516      if (suffix != null) name += ": " + suffix;
    476517    }
    477     else if (clientName != null)
    478     {
    479       name = clientName;
     518    else if (currentClient.get() != null)
     519    {
     520      name = currentClient.get().name;
    480521      if (suffix != null) name += ": " + suffix;
    481522    }
     523    else if (client != null)
     524    {
     525      name = client.name;
     526      if (suffix != null) name += ": " + suffix;
     527    }
    482528    else if (suffix != null)
    483529    {
     
    488534      name = "Unknown";
    489535    }
     536   
     537   
     538    ThreadLocal<String> activeClient = new ThreadLocal<>();
     539   
    490540    return name;
    491541  }
     
    947997    */
    948998    query.setParameter("userId", authUser.getInternalId(), TypeWrapper.H_INTEGER);
    949     query.setParameter("clientId", clientId, TypeWrapper.H_INTEGER);
     999    query.setParameter("clientId", getClientId(), TypeWrapper.H_INTEGER);
    9501000    query.setParameter("token", deviceToken, TypeWrapper.H_STRING);
    9511001    device = HibernateUtil.loadData(query);
     
    10711121   
    10721122    // Check if same client as when SessionControl was created
    1073     if (StringUtil.isEqualOrNull(externalClientId, this.externalClientId)) return true;
     1123    if (StringUtil.isEqualOrNull(externalClientId, getExternalClientId())) return true;
    10741124   
    10751125    // If no external ID or no user is logged in we do not allow it
     
    11611211
    11621212    // Load settings
    1163     if (getClientId() != 0)
    1164     {
    1165       li.userClientSettings = loadUserClientSettings(session, userData.getId(), clientId);
     1213    if (client != null)
     1214    {
     1215      li.userClientSettings = loadUserClientSettings(session, userData.getId(), client.id);
    11661216    }
    11671217    li.userDefaultSettings = loadUserDefaultSettings(session, userData.getId());
     
    27222772    if (!userData.isMultiuserAccount())
    27232773    {
    2724       if (clientId != 0)
    2725       {
    2726         ClientData clientData = HibernateUtil.loadData(session, ClientData.class, clientId);
     2774      if (client != null)
     2775      {
     2776        ClientData clientData = HibernateUtil.loadData(session, ClientData.class, client.id);
    27272777        org.hibernate.query.Query<UserClientSettingData> query =
    27282778          HibernateUtil.getPredefinedQuery(session, "LOAD_USER_CLIENT_SETTINGS", UserClientSettingData.class);
     
    30063056  }
    30073057 
     3058  private static class ClientInfo
     3059  {
     3060   
     3061    ClientInfo(int id, String externalId, String name)
     3062    {
     3063      this.id = id;
     3064      this.externalId = externalId;
     3065      this.name = name;
     3066    }
     3067   
     3068    final int id;
     3069    final String name;
     3070    final String externalId;
     3071  }
    30083072}
  • trunk/src/core/net/sf/basedb/core/log/TransactionDetails.java

    r7946 r7950  
    6262    this.userId = sc.getLoggedInUserId();
    6363    this.sessionId = sc.getCurrentSessionId();
    64     this.clientId = sc.getClientId();
     64    this.clientId = sc.getCurrentClientId();
    6565    this.projectId = sc.getActiveProjectId();
    6666    this.jobId = sc.getJobId();
Note: See TracChangeset for help on using the changeset viewer.