package org.gcube.resource.management.quota.manager.check; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import org.gcube.accounting.analytics.Filter; import org.gcube.resource.management.quota.library.quotalist.TimeInterval; import org.gcube.resource.management.quota.library.status.QuotaStorageStatus; import org.gcube.resource.management.quota.manager.util.Constants; import org.gcube.resource.management.quota.manager.util.ConstantsDb; import org.gcube.resource.management.quota.manager.util.DiscoveryConfiguration; import org.gcube.resource.management.quota.manager.util.QuotaUsageServiceValue; import org.gcube.resource.management.quota.manager.util.QuotaUsageStorageValue; import org.gcube.resource.management.quota.manager.util.SendNotification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * QuotaUsage * * @author Alessandro Pieve (alessandro.pieve@isti.cnr.it) * */ public class QuotaUsage { private static Logger log = LoggerFactory.getLogger(QuotaUsage.class); private DiscoveryConfiguration discoveryCheck; private SendNotification sendNotification; public QuotaUsage(DiscoveryConfiguration discoveryCheck){ super(); this.discoveryCheck=discoveryCheck; sendNotification=new SendNotification(discoveryCheck); }; public List userExceedQuota =new ArrayList(); public void insertServiceQuota(QuotaUsageServiceValue usageSerVal) throws Exception { String context_label=usageSerVal.getContext().replace('/', '_').toUpperCase(); Connection connection = getDBConnection(); Statement stmt = null; try { connection.setAutoCommit(false); stmt = connection.createStatement(); String periodQuota=usageSerVal.getTemporalConstraint().getAggregationMode().toString(); if (!verifyTable(connection,ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_SERVICE+ConstantsDb.SEPARATOR+ context_label+ConstantsDb.SEPARATOR+periodQuota)){ String queryCreate="CREATE TABLE "+ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_SERVICE+ConstantsDb.SEPARATOR+ context_label+ConstantsDb.SEPARATOR+periodQuota+"" + "(CALLERTYPE varchar(255),IDENTIFIER varchar(255) ,SERVICE varchar(255)," + "ACCESSTYPE varchar(50),QUOTAASSIGNED DOUBLE PRECISION, QUOTAUSAGE DOUBLE PRECISION,POLICY integer," + "primary key(CALLERTYPE,IDENTIFIER,SERVICE))"; stmt.execute(queryCreate); } String serviceIdentifier = ""; for (Filter tmp:usageSerVal.getFilters()){ serviceIdentifier=serviceIdentifier+tmp.getValue()+":"; } //TODO serviceIdentifier=serviceIdentifier+"0"; String queryVerify="SELECT count(*) FROM "+ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_STORAGE+ConstantsDb.SEPARATOR+periodQuota+"" + " WHERE IDENTIFIER ='"+usageSerVal.getIdentifier()+"'"; ResultSet rs = stmt.executeQuery(queryVerify); rs.next(); String queryInsert; if (rs.getInt(1)==0){ queryInsert="INSERT into "+ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_SERVICE+ConstantsDb.SEPARATOR+ context_label+ConstantsDb.SEPARATOR+periodQuota+"" + " (CALLERTYPE,IDENTIFIER, SERVICE,ACCESSTYPE,QUOTAASSIGNED, QUOTAUSAGE) VALUES('"+usageSerVal.getCallerType()+"'," + "'"+usageSerVal.getIdentifier()+"','"+serviceIdentifier+"'," +"'"+usageSerVal.getAccessType()+"'," +usageSerVal.getdQuota()+","+usageSerVal.getD()+")"; }else{ queryInsert="UPDATE "+ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_SERVICE+ConstantsDb.SEPARATOR+ context_label+ConstantsDb.SEPARATOR+periodQuota+"" + "SET ACCESSTYPE='"+usageSerVal.getAccessType()+"' ," + "QUOTAASSIGNED="+usageSerVal.getdQuota()+" ," + "QUOTAUSAGE="+usageSerVal.getD()+"" + "WHERE CALLERTYPE='"+usageSerVal.getCallerType()+"' AND" + " IDENTIFIER='"+usageSerVal.getIdentifier()+"' AND" + " SERVICE='"+serviceIdentifier+"'"; } log.debug("Insert data into table:{}",queryInsert); stmt.execute(queryInsert); stmt.close(); connection.commit(); } catch (SQLException e) { log.error("Sql error Message " + e); } catch (Exception e) { log.error("Exception error Message " + e); } finally { connection.close(); } } public void insertStorageQuota(QuotaUsageStorageValue usageStorVal) throws Exception { Connection connection = getDBConnection(); Statement stmt = null; try { Boolean notificationWarning1 =false; Boolean notificationWarning2 =false; Boolean notificationExceed =false; Double quotaAssignedOld = 0.0; connection.setAutoCommit(false); stmt = connection.createStatement(); String periodQuota=ConstantsDb.DATABASE_PERIOD_TOTAL; if (usageStorVal.getTemporalConstraint()!=null){ periodQuota=usageStorVal.getTemporalConstraint().getAggregationMode().toString(); } if (!verifyTable(connection,ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_STORAGE+ ConstantsDb.SEPARATOR+periodQuota)){ String queryCreate="CREATE TABLE "+ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_STORAGE+ConstantsDb.SEPARATOR+periodQuota+"" + "(IDENTIFIER varchar(255) primary key,QUOTAASSIGNED DOUBLE PRECISION, QUOTAUSAGE DOUBLE PRECISION, " + "NOTIFICATIONWARNING1 boolean default false,NOTIFICATIONWARNING2 boolean default false,NOTIFICATIONEXCEED boolean default false)"; log.debug("Create table:{}",queryCreate); stmt.execute(queryCreate); } Double percent=((usageStorVal.getD()/usageStorVal.getdQuota())*100); percent=Math.round(percent * 100.0) / 100.0; log.debug("Quota Percent quota:{} used:{},use:{}",usageStorVal.getdQuota(),usageStorVal.getD(),percent); String queryVerify="SELECT NOTIFICATIONWARNING1,NOTIFICATIONWARNING2,NOTIFICATIONEXCEED,QUOTAASSIGNED FROM "+ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_STORAGE+ConstantsDb.SEPARATOR+periodQuota+"" + " WHERE IDENTIFIER ='"+usageStorVal.getIdentifier()+"'"; ResultSet rs = stmt.executeQuery(queryVerify); while (rs.next()) { notificationWarning1 = rs.getBoolean("NOTIFICATIONWARNING1"); notificationWarning2 = rs.getBoolean("NOTIFICATIONWARNING2"); notificationExceed = rs.getBoolean("NOTIFICATIONEXCEED"); quotaAssignedOld= rs.getDouble("QUOTAASSIGNED"); } if (quotaAssignedOld!=usageStorVal.getdQuota()){ //verify if your quota assigned is changed log.debug("quota changed old value:{} new value:{}",quotaAssignedOld,usageStorVal.getdQuota()); } //verify if a getdQuota() == -1 considery a infinity quota log.debug("usageStorVal.getdQuota()!=-1 :"+usageStorVal.getdQuota()); if (usageStorVal.getdQuota()!=-1){ if ((percent>Constants.LIMIT_MSG_QUOTA_PERC_USAGE_1)&&(percentConstants.LIMIT_MSG_QUOTA_PERC_USAGE_2)&&(percent<100)){ //verify if your quota is between 95 and 100 % second warning if (!notificationWarning2){ sendNotification.sendNotificationUser(usageStorVal.getIdentifier(),usageStorVal.getdQuota(),usageStorVal.getD(),percent,"warning"); notificationWarning2=true; notificationExceed=false; } } else if ((percent>=100)){ //your quota is exceed log.debug("Quota exceed for:{} identifier:{} notification:{} ",percent,usageStorVal.getIdentifier(),notificationExceed); if (!notificationExceed){ sendNotification.sendNotificationUser(usageStorVal.getIdentifier(),usageStorVal.getdQuota(),usageStorVal.getD(),percent,"exceed"); userExceedQuota.add(usageStorVal.getIdentifier()); notificationExceed=true; } } else if (notificationWarning1 || notificationWarning2 || notificationExceed){ //your quota value is restored log.debug("---Quota reset for identifier:{} and usage :{} and quota:{}", usageStorVal.getIdentifier(),usageStorVal.getdQuota(),usageStorVal.getD()); log.debug("---Quota reset for notificationWarning1:{} and notificationWarning2 :{} and notificationExceed:{}", notificationWarning1,notificationWarning2,notificationExceed); sendNotification.sendNotificationUser(usageStorVal.getIdentifier(),usageStorVal.getdQuota(),usageStorVal.getD(),percent,"reset"); notificationWarning1=false; notificationWarning2=false; notificationExceed=false; } } queryVerify="SELECT count(*) FROM "+ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_STORAGE+ConstantsDb.SEPARATOR+periodQuota+"" + " WHERE IDENTIFIER ='"+usageStorVal.getIdentifier()+"'"; rs = stmt.executeQuery(queryVerify); rs.next(); String queryInsert; if (rs.getInt(1)==0){ queryInsert="INSERT into "+ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_STORAGE+ConstantsDb.SEPARATOR+periodQuota+"" + " (IDENTIFIER, QUOTAASSIGNED, QUOTAUSAGE,NOTIFICATIONWARNING1,NOTIFICATIONWARNING2,NOTIFICATIONEXCEED) VALUES('"+usageStorVal.getIdentifier()+"'," +usageStorVal.getdQuota()+","+usageStorVal.getD()+","+notificationWarning1+"" + ","+notificationWarning2+"" + ","+notificationExceed+")"; }else{ queryInsert="UPDATE "+ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_STORAGE+ConstantsDb.SEPARATOR+periodQuota+"" + " set QUOTAASSIGNED="+usageStorVal.getdQuota()+"," + "QUOTAUSAGE="+usageStorVal.getD()+" ," + "NOTIFICATIONEXCEED="+notificationExceed+" ," + "NOTIFICATIONWARNING1="+notificationWarning1+"," + "NOTIFICATIONWARNING2="+notificationWarning2+" " + "where IDENTIFIER='"+usageStorVal.getIdentifier()+"'"; } log.debug("Insert data into table:{}",queryInsert); stmt.execute(queryInsert); stmt.close(); connection.commit(); } catch (SQLException e) { log.error("Sql error Message " + e); } catch (Exception e) { log.error("Exception error Message " + e); } finally { connection.close(); } } public void SendNotificationAdmin() { try { log.debug("Send Notification to Admin"); sendNotification.SendNotificationAdmin(userExceedQuota); userExceedQuota.clear(); } catch (Exception e) { e.printStackTrace(); } } public QuotaStorageStatus selectStorageQuota(String identifier, TimeInterval interval)throws Exception { Connection connection = getDBConnection(); QuotaStorageStatus quotaStorageStatus = null; Statement stmt = null; try { connection.setAutoCommit(false); stmt = connection.createStatement(); String periodQuota=ConstantsDb.DATABASE_PERIOD_TOTAL; Double quotaAssigned = 0.0; Double quotaUsage=0.0; //Quota Storage Total if (interval.equals(TimeInterval.FOREVER)){ String query="SELECT * FROM "+ConstantsDb.DATABASE_PREFIX+ConstantsDb.SEPARATOR+ConstantsDb.DATABASE_TYPE_STORAGE+ConstantsDb.SEPARATOR+periodQuota+"" + " WHERE IDENTIFIER='"+identifier+"'"; ResultSet rs = stmt.executeQuery(query); while (rs.next()) { quotaAssigned=rs.getDouble("QUOTAASSIGNED"); quotaUsage=rs.getDouble("QUOTAUSAGE"); } } stmt.close(); connection.commit(); quotaStorageStatus =new QuotaStorageStatus(identifier,interval,quotaAssigned,quotaUsage); } catch (SQLException e) { log.error("Sql error Message " + e); } catch (Exception e) { log.error("Exception error Message " + e); } finally { connection.close(); } return quotaStorageStatus; } /** * Verify if exist a table * @param connection * @param tableName * @return boolean true if exist * @throws SQLException */ private Boolean verifyTable(Connection connection, String tableName) throws SQLException{ boolean tExists = false; DatabaseMetaData dbm = connection.getMetaData(); ResultSet tables = dbm.getTables(null, null, tableName, null); if (tables.next()) { tExists = true; } log.trace("verifyTable :{} result:{}",tableName,tExists); return tExists; } /** * Init connection db * @return connection */ private Connection getDBConnection() { Connection dbConnection = null; try { Class.forName(ConstantsDb.DB_DRIVER); } catch (ClassNotFoundException e) { log.error("error class not found exception",e); } try { String nameConnection="jdbc:postgresql://"+discoveryCheck.getDatabasePath()+"/"+discoveryCheck.getDbname(); dbConnection = DriverManager.getConnection(nameConnection, discoveryCheck.getUsernameDb(),discoveryCheck.getPwdnameDb()); return dbConnection; } catch (SQLException e) { log.error("error connecting to db",e); } return dbConnection; } }