001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.activemq.usage;
018    
019    import java.util.List;
020    import java.util.concurrent.CopyOnWriteArrayList;
021    import java.util.concurrent.ThreadPoolExecutor;
022    
023    import org.apache.activemq.Service;
024    import org.apache.activemq.broker.scheduler.JobSchedulerStore;
025    import org.apache.activemq.store.PListStore;
026    import org.apache.activemq.store.PersistenceAdapter;
027    
028    /**
029     * Holder for Usage instances for memory, store and temp files Main use case is
030     * manage memory usage.
031     *
032     * @org.apache.xbean.XBean
033     *
034     */
035    public class SystemUsage implements Service {
036    
037        private SystemUsage parent;
038        private String name;
039        private MemoryUsage memoryUsage;
040        private StoreUsage storeUsage;
041        private TempUsage tempUsage;
042        private ThreadPoolExecutor executor;
043        private JobSchedulerUsage jobSchedulerUsage;
044    
045        /**
046         * True if someone called setSendFailIfNoSpace() on this particular usage
047         * manager
048         */
049        private boolean sendFailIfNoSpaceExplicitySet;
050        private boolean sendFailIfNoSpace;
051        private boolean sendFailIfNoSpaceAfterTimeoutExplicitySet;
052        private long sendFailIfNoSpaceAfterTimeout = 0;
053    
054        private final List<SystemUsage> children = new CopyOnWriteArrayList<SystemUsage>();
055    
056        public SystemUsage() {
057            this("default", null, null, null);
058        }
059    
060        public SystemUsage(String name, PersistenceAdapter adapter, PListStore tempStore, JobSchedulerStore jobSchedulerStore) {
061            this.parent = null;
062            this.name = name;
063            this.memoryUsage = new MemoryUsage(name + ":memory");
064            this.storeUsage = new StoreUsage(name + ":store", adapter);
065            this.tempUsage = new TempUsage(name + ":temp", tempStore);
066            this.jobSchedulerUsage = new JobSchedulerUsage(name + ":jobScheduler", jobSchedulerStore);
067            this.memoryUsage.setExecutor(getExecutor());
068            this.storeUsage.setExecutor(getExecutor());
069            this.tempUsage.setExecutor(getExecutor());
070        }
071    
072        public SystemUsage(SystemUsage parent, String name) {
073            this.parent = parent;
074            this.executor = parent.getExecutor();
075            this.name = name;
076            this.memoryUsage = new MemoryUsage(parent.memoryUsage, name + ":memory");
077            this.storeUsage = new StoreUsage(parent.storeUsage, name + ":store");
078            this.tempUsage = new TempUsage(parent.tempUsage, name + ":temp");
079            this.jobSchedulerUsage = new JobSchedulerUsage(parent.jobSchedulerUsage, name + ":jobScheduler");
080            this.memoryUsage.setExecutor(getExecutor());
081            this.storeUsage.setExecutor(getExecutor());
082            this.tempUsage.setExecutor(getExecutor());
083        }
084    
085        public String getName() {
086            return name;
087        }
088    
089        /**
090         * @return the memoryUsage
091         */
092        public MemoryUsage getMemoryUsage() {
093            return this.memoryUsage;
094        }
095    
096        /**
097         * @return the storeUsage
098         */
099        public StoreUsage getStoreUsage() {
100            return this.storeUsage;
101        }
102    
103        /**
104         * @return the tempDiskUsage
105         */
106        public TempUsage getTempUsage() {
107            return this.tempUsage;
108        }
109    
110        /**
111         * @return the schedulerUsage
112         */
113        public JobSchedulerUsage getJobSchedulerUsage() {
114            return this.jobSchedulerUsage;
115        }
116    
117        @Override
118        public String toString() {
119            return "UsageManager(" + getName() + ")";
120        }
121    
122        @Override
123        public void start() {
124            if (parent != null) {
125                parent.addChild(this);
126            }
127            this.memoryUsage.start();
128            this.storeUsage.start();
129            this.tempUsage.start();
130            this.jobSchedulerUsage.start();
131        }
132    
133        @Override
134        public void stop() {
135            if (parent != null) {
136                parent.removeChild(this);
137            }
138            this.memoryUsage.stop();
139            this.storeUsage.stop();
140            this.tempUsage.stop();
141            this.jobSchedulerUsage.stop();
142        }
143    
144        /**
145         * Sets whether or not a send() should fail if there is no space free. The
146         * default value is false which means to block the send() method until space
147         * becomes available
148         */
149        public void setSendFailIfNoSpace(boolean failProducerIfNoSpace) {
150            sendFailIfNoSpaceExplicitySet = true;
151            this.sendFailIfNoSpace = failProducerIfNoSpace;
152        }
153    
154        public boolean isSendFailIfNoSpace() {
155            if (sendFailIfNoSpaceExplicitySet || parent == null) {
156                return sendFailIfNoSpace;
157            } else {
158                return parent.isSendFailIfNoSpace();
159            }
160        }
161    
162        private void addChild(SystemUsage child) {
163            children.add(child);
164        }
165    
166        private void removeChild(SystemUsage child) {
167            children.remove(child);
168        }
169    
170        public SystemUsage getParent() {
171            return parent;
172        }
173    
174        public void setParent(SystemUsage parent) {
175            this.parent = parent;
176        }
177    
178        public boolean isSendFailIfNoSpaceExplicitySet() {
179            return sendFailIfNoSpaceExplicitySet;
180        }
181    
182        public void setSendFailIfNoSpaceExplicitySet(boolean sendFailIfNoSpaceExplicitySet) {
183            this.sendFailIfNoSpaceExplicitySet = sendFailIfNoSpaceExplicitySet;
184        }
185    
186        public long getSendFailIfNoSpaceAfterTimeout() {
187            if (sendFailIfNoSpaceAfterTimeoutExplicitySet || parent == null) {
188                return sendFailIfNoSpaceAfterTimeout;
189            } else {
190                return parent.getSendFailIfNoSpaceAfterTimeout();
191            }
192        }
193    
194        public void setSendFailIfNoSpaceAfterTimeout(long sendFailIfNoSpaceAfterTimeout) {
195            this.sendFailIfNoSpaceAfterTimeoutExplicitySet = true;
196            this.sendFailIfNoSpaceAfterTimeout = sendFailIfNoSpaceAfterTimeout;
197        }
198    
199        public void setName(String name) {
200            this.name = name;
201            this.memoryUsage.setName(name + ":memory");
202            this.storeUsage.setName(name + ":store");
203            this.tempUsage.setName(name + ":temp");
204            this.jobSchedulerUsage.setName(name + ":jobScheduler");
205        }
206    
207        public void setMemoryUsage(MemoryUsage memoryUsage) {
208            if (memoryUsage.getName() == null) {
209                memoryUsage.setName(this.memoryUsage.getName());
210            }
211            if (parent != null) {
212                memoryUsage.setParent(parent.memoryUsage);
213            }
214            this.memoryUsage = memoryUsage;
215            this.memoryUsage.setExecutor(getExecutor());
216        }
217    
218        public void setStoreUsage(StoreUsage storeUsage) {
219            if (storeUsage.getStore() == null) {
220                storeUsage.setStore(this.storeUsage.getStore());
221            }
222            if (storeUsage.getName() == null) {
223                storeUsage.setName(this.storeUsage.getName());
224            }
225            if (parent != null) {
226                storeUsage.setParent(parent.storeUsage);
227            }
228            this.storeUsage = storeUsage;
229            this.storeUsage.setExecutor(executor);
230        }
231    
232        public void setTempUsage(TempUsage tempDiskUsage) {
233            if (tempDiskUsage.getStore() == null) {
234                tempDiskUsage.setStore(this.tempUsage.getStore());
235            }
236            if (tempDiskUsage.getName() == null) {
237                tempDiskUsage.setName(this.tempUsage.getName());
238            }
239            if (parent != null) {
240                tempDiskUsage.setParent(parent.tempUsage);
241            }
242            this.tempUsage = tempDiskUsage;
243            this.tempUsage.setExecutor(getExecutor());
244        }
245    
246        public void setJobSchedulerUsage(JobSchedulerUsage jobSchedulerUsage) {
247            if (jobSchedulerUsage.getStore() == null) {
248                jobSchedulerUsage.setStore(this.jobSchedulerUsage.getStore());
249            }
250            if (jobSchedulerUsage.getName() == null) {
251                jobSchedulerUsage.setName(this.jobSchedulerUsage.getName());
252            }
253            if (parent != null) {
254                jobSchedulerUsage.setParent(parent.jobSchedulerUsage);
255            }
256            this.jobSchedulerUsage = jobSchedulerUsage;
257            this.jobSchedulerUsage.setExecutor(getExecutor());
258        }
259    
260        /**
261         * @return the executor
262         */
263        public ThreadPoolExecutor getExecutor() {
264            return this.executor;
265        }
266    
267        /**
268         * @param executor
269         *            the executor to set
270         */
271        public void setExecutor(ThreadPoolExecutor executor) {
272            this.executor = executor;
273            if (this.memoryUsage != null) {
274                this.memoryUsage.setExecutor(this.executor);
275            }
276            if (this.storeUsage != null) {
277                this.storeUsage.setExecutor(this.executor);
278            }
279            if (this.tempUsage != null) {
280                this.tempUsage.setExecutor(this.executor);
281            }
282            if(this.jobSchedulerUsage != null) {
283                this.jobSchedulerUsage.setExecutor(this.executor);
284            }
285        }
286    }