001: /**
002: * Sequoia: Database clustering technology.
003: * Copyright (C) 2006 Continuent.
004: * Contact: sequoia@continuent.org
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: * Initial developer(s): Jeff Mesnil.
019: * Contributor(s): ______________________.
020: */package org.continuent.sequoia.controller.recoverylog;
021:
022: import java.sql.SQLException;
023: import java.util.Arrays;
024: import java.util.HashMap;
025: import java.util.Map;
026:
027: import javax.management.NotCompliantMBeanException;
028: import javax.management.openmbean.CompositeData;
029: import javax.management.openmbean.CompositeDataSupport;
030: import javax.management.openmbean.CompositeType;
031: import javax.management.openmbean.OpenDataException;
032: import javax.management.openmbean.OpenType;
033: import javax.management.openmbean.SimpleType;
034: import javax.management.openmbean.TabularData;
035: import javax.management.openmbean.TabularDataSupport;
036: import javax.management.openmbean.TabularType;
037:
038: import org.continuent.sequoia.common.i18n.Translate;
039: import org.continuent.sequoia.common.jmx.mbeans.RecoveryLogControlMBean;
040: import org.continuent.sequoia.common.log.Trace;
041: import org.continuent.sequoia.controller.jmx.AbstractStandardMBean;
042:
043: /**
044: * RecoveryLogControlMBean implemementation.<br />
045: * Used to manage a RecoveryLog.
046: *
047: * @see org.continuent.sequoia.controller.recoverylog.RecoveryLog
048: */
049: public class RecoveryLogControl extends AbstractStandardMBean implements
050: RecoveryLogControlMBean {
051:
052: private RecoveryLog managedRecoveryLog;
053: private final Trace logger = Trace
054: .getLogger("org.continuent.sequoia.controller.recoverylog"); //$NON-NLS-1$
055:
056: private static final int ENTRIES_PER_DUMP = 100;
057:
058: private TabularType logEntriesType;
059: private CompositeType logEntryType;
060:
061: /**
062: * Creates a new <code>RecoveryLogControl</code> object
063: *
064: * @param recoveryLog the managed RecoveryLog
065: * @throws NotCompliantMBeanException if this mbean is not compliant
066: */
067: public RecoveryLogControl(RecoveryLog recoveryLog)
068: throws NotCompliantMBeanException {
069: super (RecoveryLogControlMBean.class);
070: this .managedRecoveryLog = recoveryLog;
071: defineTypes();
072: }
073:
074: /**
075: * Defines the OpenType used by this mbean.
076: *
077: * @see #dump(int)
078: */
079: private void defineTypes() {
080: try {
081: String[] headers = getHeaders();
082: logEntryType = new CompositeType(
083: "LogEntry", //$NON-NLS-1$
084: Translate
085: .get("RecoveryLogControl.LogEntryDescription"), headers, headers, //$NON-NLS-1$
086: getEntryTypes(headers.length));
087: logEntriesType = new TabularType(
088: "LogEntries", //$NON-NLS-1$
089: Translate
090: .get("RecoveryLogControl.LogEntriesDescription"), logEntryType, headers); //$NON-NLS-1$
091: } catch (OpenDataException e) {
092: if (logger.isWarnEnabled()) {
093: logger.warn(Translate
094: .get("RecoveryLogControl.openTypeWarning"), e); //$NON-NLS-1$
095: }
096: }
097: }
098:
099: private OpenType[] getEntryTypes(int length) {
100: // all column are returned as String
101: OpenType[] types = new OpenType[length];
102: for (int i = 0; i < types.length; i++) {
103: types[i] = SimpleType.STRING;
104: }
105: return types;
106: }
107:
108: /**
109: * @see org.continuent.sequoia.controller.jmx.AbstractStandardMBean#getAssociatedString()
110: */
111: public String getAssociatedString() {
112: return "recoverylog"; //$NON-NLS-1$
113: }
114:
115: /**
116: * @see org.continuent.sequoia.common.jmx.mbeans.RecoveryLogControlMBean#getHeaders()
117: */
118: public String[] getHeaders() {
119: return managedRecoveryLog.getColumnNames();
120: }
121:
122: /**
123: * @see org.continuent.sequoia.common.jmx.mbeans.RecoveryLogControlMBean#dump(int)
124: */
125: public TabularData dump(long from) {
126: if (logger.isDebugEnabled()) {
127: logger.debug("dumping recovery log from index " + from
128: + " (" + ENTRIES_PER_DUMP + " entries per page)");
129: }
130: String[][] entries = managedRecoveryLog.getLogEntries(from,
131: ENTRIES_PER_DUMP);
132: TabularData result = toTabularData(entries);
133: return result;
134: }
135:
136: /**
137: * @see org.continuent.sequoia.common.jmx.mbeans.RecoveryLogControlMBean#getEntriesPerDump()
138: */
139: public int getEntriesPerDump() {
140: return ENTRIES_PER_DUMP;
141: }
142:
143: /**
144: * @see org.continuent.sequoia.common.jmx.mbeans.RecoveryLogControlMBean#getIndexes()
145: */
146: public long[] getIndexes() {
147: try {
148: return managedRecoveryLog.getIndexes();
149: } catch (SQLException e) {
150: if (logger.isWarnEnabled()) {
151: // FIXME we should specify the VBD the managed recovery log belongs to
152: logger
153: .warn(
154: "unable to get the min and max indexes of the recovery log",
155: e);
156: }
157: return null;
158: }
159: }
160:
161: /**
162: * @see org.continuent.sequoia.common.jmx.mbeans.RecoveryLogControlMBean#getEntries()
163: */
164: public long getEntries() {
165: try {
166: return managedRecoveryLog.getNumberOfLogEntries();
167: } catch (SQLException e) {
168: if (logger.isWarnEnabled()) {
169: // FIXME we should specify the VBD the managed recovery log belongs to
170: logger
171: .warn(
172: "unable to get the number of log entries in the recovery log",
173: e);
174: }
175: return -1;
176: }
177: }
178:
179: public TabularData getRequestsInTransaction(long tid) {
180: String[][] entriesInTransaction = managedRecoveryLog
181: .getLogEntriesInTransaction(tid);
182: TabularData result = toTabularData(entriesInTransaction);
183: return result;
184: }
185:
186: /**
187: * Helper method to convert a matrix of String to a TabularData.
188: *
189: * @param entries a matrix of String
190: * @return a TabularData
191: */
192: private TabularData toTabularData(String[][] entries) {
193: TabularData entriesData = new TabularDataSupport(logEntriesType);
194: for (int i = 0; i < entries.length; i++) {
195: String[] entry = entries[i];
196: CompositeData entryData = toCompositeData(entry);
197: if (entryData != null) {
198: entriesData.put(entryData);
199: }
200: }
201: return entriesData;
202: }
203:
204: /**
205: * Helper method to convert a array of String to a CompositeData.<br />
206: * <strong>this method assumes that all the types of the CompositeData are of
207: * SimpleType.STRING.</strong>
208: *
209: * @param entry an array of String
210: * @return a CompositeData
211: * @see SimpleType#STRING
212: */
213: private CompositeData toCompositeData(String[] entry) {
214: try {
215: CompositeData entryData = new CompositeDataSupport(
216: logEntryType, getHeaders(), entry);
217: return entryData;
218: } catch (OpenDataException e) {
219: if (logger.isWarnEnabled()) {
220: logger
221: .warn(
222: Translate
223: .get(
224: "RecoveryLogControl.conversionWarning", Arrays.asList(entry)), e); //$NON-NLS-1$
225: }
226: return null;
227: }
228: }
229:
230: /**
231: * @see org.continuent.sequoia.common.jmx.mbeans.RecoveryLogControlMBean#getCheckpoints()
232: */
233: public Map getCheckpoints() {
234: try {
235: return managedRecoveryLog.getCheckpoints();
236: } catch (SQLException e) {
237: if (logger.isWarnEnabled()) {
238: logger.warn(e.getMessage(), e);
239: }
240: return new HashMap();
241: }
242: }
243: }
|