001/* 002 * Copyright 2016 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.ametys.web.cache.monitoring.process.access; 018 019import java.util.List; 020 021import org.apache.ibatis.session.SqlSession; 022 023import org.ametys.core.datasource.AbstractMyBatisDAO; 024import org.ametys.core.util.DateUtils; 025 026import com.google.common.collect.LinkedListMultimap; 027import com.google.common.collect.ListMultimap; 028 029/** 030 * The RessourceAccessMonitor collects the resources that have been requested, 031 * and export them into a database. 032 */ 033public class ResourceAccessComponent extends AbstractMyBatisDAO 034{ 035 /** Avalon ROLE. */ 036 public static final String ROLE = ResourceAccessComponent.class.getName(); 037 038 /** List of pending {@link ResourceAccess} waiting to be exported to the database. */ 039 protected ListMultimap<String, ResourceAccess> _pendingRecords = LinkedListMultimap.create(); 040 041 /** 042 * Add a new {@link ResourceAccess} to the monitored resources. 043 * @param ra The resource access object. 044 */ 045 public void addAccessRecord(ResourceAccess ra) 046 { 047 synchronized (this) 048 { 049 _pendingRecords.put(ra.getClass().getName(), ra); 050 } 051 } 052 053 /** 054 * Call this method to transfer pendings resource access from memory to database 055 * This is normally called by a scheduler 056 */ 057 public void exportPendings() 058 { 059 long start = 0; 060 int successCount = 0; 061 ListMultimap<String, ResourceAccess> resourcesAccesstoExport; 062 063 if (getLogger().isDebugEnabled()) 064 { 065 getLogger().debug("Start to insert pending records."); 066 start = System.currentTimeMillis(); 067 } 068 069 // Copy the current pending records by switching references 070 synchronized (this) 071 { 072 resourcesAccesstoExport = _pendingRecords; 073 _pendingRecords = LinkedListMultimap.create(); 074 } 075 076 // Export 077 if (!resourcesAccesstoExport.isEmpty()) 078 { 079 successCount = _fillDatabase(resourcesAccesstoExport); 080 } 081 082 if (getLogger().isDebugEnabled()) 083 { 084 String durationStr = DateUtils.formatDuration(System.currentTimeMillis() - start); 085 getLogger().debug(String.format("%s/%s pending records exported into database in %s", successCount, resourcesAccesstoExport.size(), durationStr)); 086 } 087 } 088 089 private int _fillDatabase(ListMultimap<String, ResourceAccess> resourcesAccess) 090 { 091 int success = 0; 092 for (String resourceAccessType : resourcesAccess.keySet()) 093 { 094 try (SqlSession sqlSession = getSession()) 095 { 096 success += _fillDatabase(sqlSession, resourcesAccess.get(resourceAccessType)); 097 098 // Commit the transaction. 099 sqlSession.commit(); 100 } 101 } 102 return success; 103 } 104 105 private int _fillDatabase(SqlSession sqlSession, List<ResourceAccess> resourcesAccess) 106 { 107 try 108 { 109 for (ResourceAccess ra : resourcesAccess) 110 { 111 sqlSession.insert(ra.getInsertStatementId(), ra.getInsertStatementParameters()); 112 } 113 114 return resourcesAccess.size(); 115 } 116 catch (Exception e) 117 { 118 getLogger().error("Exception exception while inserting new records to the database", e); 119 return 0; 120 } 121 } 122}