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.plugins.site.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; 025import org.ametys.runtime.config.Config; 026 027import com.google.common.collect.LinkedListMultimap; 028import com.google.common.collect.ListMultimap; 029 030/** 031 * The RessourceAccessMonitor collects the resources that have been requested, 032 * and export them into a database. 033 */ 034public class ResourceAccessComponent extends AbstractMyBatisDAO 035{ 036 /** Avalon ROLE. */ 037 public static final String ROLE = ResourceAccessComponent.class.getName(); 038 039 /** List of pending {@link ResourceAccess} waiting to be exported to the database. */ 040 protected ListMultimap<String, ResourceAccess> _pendingRecords = LinkedListMultimap.create(); 041 042 /** 043 * Add a new {@link ResourceAccess} to the monitored resources. 044 * @param ra The resource access object. 045 */ 046 public void addAccessRecord(ResourceAccess ra) 047 { 048 boolean enabled = Config.getInstance().getValueAsBoolean("front.cache.monitoring.schedulers.enable"); 049 if (!enabled || ra == null) 050 { 051 return; 052 } 053 054 synchronized (this) 055 { 056 _pendingRecords.put(ra.getClass().getName(), ra); 057 } 058 } 059 060 /** 061 * Call this method to transfer pendings resource access from memory to database 062 * This is normally called by a scheduler 063 */ 064 public void exportPendings() 065 { 066 long start = 0; 067 int successCount = 0; 068 ListMultimap<String, ResourceAccess> resourcesAccesstoExport; 069 070 if (getLogger().isDebugEnabled()) 071 { 072 getLogger().debug("Start to insert pending records."); 073 start = System.currentTimeMillis(); 074 } 075 076 // Copy the current pending records by switching references 077 synchronized (this) 078 { 079 resourcesAccesstoExport = _pendingRecords; 080 _pendingRecords = LinkedListMultimap.create(); 081 } 082 083 // Export 084 if (!resourcesAccesstoExport.isEmpty()) 085 { 086 successCount = _fillDatabase(resourcesAccesstoExport); 087 } 088 089 if (getLogger().isDebugEnabled()) 090 { 091 String durationStr = DateUtils.formatDuration(System.currentTimeMillis() - start); 092 getLogger().debug(String.format("%s/%s pending records exported into database in %s", successCount, resourcesAccesstoExport.size(), durationStr)); 093 } 094 } 095 096 private int _fillDatabase(ListMultimap<String, ResourceAccess> resourcesAccess) 097 { 098 int success = 0; 099 for (String resourceAccessType : resourcesAccess.keySet()) 100 { 101 try (SqlSession sqlSession = getSession()) 102 { 103 success += _fillDatabase(sqlSession, resourcesAccess.get(resourceAccessType)); 104 105 // Commit the transaction. 106 sqlSession.commit(); 107 } 108 } 109 return success; 110 } 111 112 private int _fillDatabase(SqlSession sqlSession, List<ResourceAccess> resourcesAccess) 113 { 114 try 115 { 116 for (ResourceAccess ra : resourcesAccess) 117 { 118 sqlSession.insert(ra.getInsertStatementId(), ra.getInsertStatementParameters()); 119 } 120 121 return resourcesAccess.size(); 122 } 123 catch (Exception e) 124 { 125 getLogger().error("Exception exception while inserting new records to the database", e); 126 return 0; 127 } 128 } 129}