|
1 /* |
|
2 * CDDL HEADER START |
|
3 * |
|
4 * The contents of this file are subject to the terms of the |
|
5 * Common Development and Distribution License (the "License"). |
|
6 * You may not use this file except in compliance with the License. |
|
7 * |
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 * or http://www.opensolaris.org/os/licensing. |
|
10 * See the License for the specific language governing permissions |
|
11 * and limitations under the License. |
|
12 * |
|
13 * When distributing Covered Code, include this CDDL HEADER in each |
|
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 * If applicable, add the following below this CDDL HEADER, with the |
|
16 * fields enclosed by brackets "[]" replaced with your own identifying |
|
17 * information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 * |
|
19 * CDDL HEADER END |
|
20 */ |
|
21 |
|
22 /* |
|
23 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. |
|
24 */ |
|
25 |
|
26 package com.oracle.solaris.vp.panel.common.smf; |
|
27 |
|
28 import java.beans.*; |
|
29 import java.io.IOException; |
|
30 import java.util.Locale; |
|
31 import java.util.logging.Level; |
|
32 import javax.management.*; |
|
33 import com.oracle.solaris.rad.jmx.RadNotification; |
|
34 import com.oracle.solaris.scf.common.ScfException; |
|
35 import com.oracle.solaris.vp.panel.common.*; |
|
36 import com.oracle.solaris.vp.panel.common.api.smf_old.*; |
|
37 import com.oracle.solaris.vp.panel.common.model.*; |
|
38 import com.oracle.solaris.vp.util.misc.Enableable; |
|
39 import com.oracle.solaris.vp.util.misc.finder.Finder; |
|
40 |
|
41 @SuppressWarnings({"serial"}) |
|
42 public abstract class ServicePanelDescriptor<C extends ManagedObject> |
|
43 extends AbstractPanelDescriptor<C> implements HasService, HasServiceTracker, |
|
44 Enableable { |
|
45 |
|
46 // |
|
47 // Static data |
|
48 // |
|
49 |
|
50 public static final String PROPERTY_STATE = "state"; |
|
51 |
|
52 // |
|
53 // Instance data |
|
54 // |
|
55 |
|
56 private ServiceTracker tracker; |
|
57 private String serviceName; |
|
58 private String instanceName; |
|
59 |
|
60 private SmfEnabledProperty enabledProperty = |
|
61 new SmfEnabledProperty(PROPERTY_ENABLED, this); |
|
62 |
|
63 private PropertyChangeListener serviceListener = |
|
64 new PropertyChangeListener() { |
|
65 @Override |
|
66 public void propertyChange(PropertyChangeEvent event) { |
|
67 serviceChanged(); |
|
68 } |
|
69 }; |
|
70 |
|
71 /** |
|
72 * Handles changes to this {@code ServicePanelDescriptor}'s service. |
|
73 * This implementation listens only for {@code StateChangeNotification}s and |
|
74 * fires a {@code PropertyChangeEvent} to registered {@code |
|
75 * PropertyChangeEvent}s. Subclasses with {@code ManagedObject} children |
|
76 * may wish to override/extend this implementation. |
|
77 */ |
|
78 private NotificationListener notifyListener = |
|
79 new NotificationListener() { |
|
80 @Override |
|
81 public void handleNotification(Notification n, Object h) { |
|
82 StateChange sc = ((RadNotification)n).getPayload( |
|
83 StateChange.class); |
|
84 |
|
85 firePropertyChange(PROPERTY_STATE, null, sc.getState()); |
|
86 setStatus(); |
|
87 setStatusText(); |
|
88 try { |
|
89 refresh(false); |
|
90 } catch (Exception e) { |
|
91 getLog().log(Level.SEVERE, Finder.getString( |
|
92 "error.repository.read"), e); |
|
93 } |
|
94 } |
|
95 }; |
|
96 |
|
97 // |
|
98 // Constructors |
|
99 // |
|
100 |
|
101 public ServicePanelDescriptor(String id, ClientContext context, |
|
102 String serviceName, String instanceName) throws IOException, |
|
103 InstanceNotFoundException, TrackerException { |
|
104 |
|
105 super(id, context); |
|
106 |
|
107 this.serviceName = serviceName; |
|
108 this.instanceName = instanceName; |
|
109 |
|
110 tracker = new ServiceTracker(serviceName, instanceName, context); |
|
111 tracker.addNotificationListener(notifyListener, |
|
112 SmfUtil.NOTIFY_FILTER_STATE_CHANGE, null); |
|
113 tracker.addPropertyChangeListener(ServiceTracker.PROPERTY_SERVICE, |
|
114 serviceListener); |
|
115 |
|
116 serviceChanged(); |
|
117 setName(); |
|
118 } |
|
119 |
|
120 // |
|
121 // ManagedObject methods |
|
122 // |
|
123 |
|
124 /** |
|
125 * Stops monitoring the connection to the remote host. |
|
126 */ |
|
127 @Override |
|
128 public void dispose() { |
|
129 tracker.dispose(); |
|
130 super.dispose(); |
|
131 } |
|
132 |
|
133 /** |
|
134 * Default implementation that returns {@code null}. |
|
135 */ |
|
136 @Override |
|
137 public String getDescription() { |
|
138 String locale = Locale.getDefault().getLanguage(); |
|
139 |
|
140 try { |
|
141 return getService().getDescription(locale); |
|
142 } catch (ScfException e) { |
|
143 getLog().log(Level.SEVERE, Finder.getString("error.scf.general"), |
|
144 e); |
|
145 } |
|
146 |
|
147 return null; |
|
148 } |
|
149 |
|
150 // |
|
151 // PanelDescriptor methods |
|
152 // |
|
153 |
|
154 @Override |
|
155 public boolean getHasFullPrivileges() { |
|
156 ConnectionInfo info = getClientContext().getConnectionInfo(); |
|
157 String user = info.getRole(); |
|
158 if (user == null) { |
|
159 user = info.getUser(); |
|
160 } |
|
161 |
|
162 // XXX Provide a better diagnostic |
|
163 return "root".equals(user); |
|
164 } |
|
165 |
|
166 // |
|
167 // HasService methods |
|
168 // |
|
169 |
|
170 @Override |
|
171 public AggregatedRefreshService getService() { |
|
172 // This may be called indirectly by the superclass before tracker has |
|
173 // been instantiated |
|
174 return tracker == null ? null : tracker.getService(); |
|
175 } |
|
176 |
|
177 // |
|
178 // HasServiceTracker methods |
|
179 // |
|
180 |
|
181 @Override |
|
182 public ServiceTracker getServiceTracker() { |
|
183 return tracker; |
|
184 } |
|
185 |
|
186 // |
|
187 // Enableable methods |
|
188 // |
|
189 |
|
190 /** |
|
191 * Gets the enabled status from the {@link #getEnabledProperty enabled |
|
192 * property}. |
|
193 * |
|
194 * @return {@code true} if enabled, {@code false} if not enabled or if |
|
195 * the {@link #getEnabledProperty enabled property} has not |
|
196 * been initialized |
|
197 * |
|
198 * @see #refresh |
|
199 */ |
|
200 @Override |
|
201 public boolean isEnabled() { |
|
202 Boolean enabled = enabledProperty.getSavedValue(); |
|
203 return enabled == null ? false : enabled; |
|
204 } |
|
205 |
|
206 // |
|
207 // AbstractManagedObject methods |
|
208 // |
|
209 |
|
210 /** |
|
211 * Downgrades this {@code PanelDescriptor}'s state if the underlying service |
|
212 * is degraded. |
|
213 */ |
|
214 @Override |
|
215 protected ManagedObjectStatus getCalculatedStatus() { |
|
216 ManagedObjectStatus status = super.getCalculatedStatus(); |
|
217 |
|
218 ServiceMXBean service = getService(); |
|
219 if (service != null) { |
|
220 ManagedObjectStatus sStatus = null; |
|
221 |
|
222 try { |
|
223 SmfState state = service.getState(); |
|
224 sStatus = ServiceUtil.getPanelStatus(state); |
|
225 } catch (ScfException e) { |
|
226 getLog().log(Level.SEVERE, Finder.getString( |
|
227 "error.scf.general"), e); |
|
228 sStatus = ManagedObjectStatus.ERROR; |
|
229 } |
|
230 |
|
231 status = status.compareTo(sStatus) > 0 ? status : sStatus; |
|
232 } |
|
233 |
|
234 return status; |
|
235 } |
|
236 |
|
237 @Override |
|
238 protected String getCalculatedStatusText() { |
|
239 SmfState state = null; |
|
240 SmfState nextState = null; |
|
241 ServiceMXBean service = getService(); |
|
242 |
|
243 try { |
|
244 state = service.getState(); |
|
245 nextState = service.getNextState(); |
|
246 } catch (ScfException e) { |
|
247 getLog().log(Level.SEVERE, Finder.getString("error.scf.general"), |
|
248 e); |
|
249 } |
|
250 |
|
251 // Can handle null states |
|
252 return ServiceUtil.getStateSynopsis(state, nextState); |
|
253 } |
|
254 |
|
255 // |
|
256 // ServicePanelDescriptor methods |
|
257 // |
|
258 |
|
259 public SmfEnabledProperty getEnabledProperty() { |
|
260 return enabledProperty; |
|
261 } |
|
262 |
|
263 public String getInstanceName() { |
|
264 return instanceName; |
|
265 } |
|
266 |
|
267 public String getServiceName() { |
|
268 return serviceName; |
|
269 } |
|
270 |
|
271 /** |
|
272 * Updates this {@code PanelDescriptor} with service/repository data. This |
|
273 * default implementation updates the {@link #getEnabledProperty enabled |
|
274 * property} of this object. |
|
275 * |
|
276 * @param force |
|
277 * {@code true} to override any values that have been changed |
|
278 * but not yet saved, {@code false} otherwise |
|
279 * |
|
280 * @exception ScfException |
|
281 * if an error occurs while accessing the SMF repository |
|
282 * |
|
283 * @exception InvalidScfDataException |
|
284 * if data in the repository is invalid |
|
285 * |
|
286 * @exception MissingScfDataException |
|
287 * if data in the repository is missing |
|
288 */ |
|
289 public void refresh(boolean force) throws ScfException, |
|
290 InvalidScfDataException, MissingScfDataException { |
|
291 |
|
292 enabledProperty.updateFromRepo(force); |
|
293 } |
|
294 |
|
295 /** |
|
296 * Sets the name of this {@code ServicePanelDescriptor}. |
|
297 */ |
|
298 protected void setName() { |
|
299 String name = null; |
|
300 String locale = Locale.getDefault().getLanguage(); |
|
301 |
|
302 try { |
|
303 name = getService().getCommonName(locale); |
|
304 } catch (ScfException e) { |
|
305 getLog().log(Level.SEVERE, Finder.getString("error.scf.general"), |
|
306 e); |
|
307 } |
|
308 |
|
309 if (name == null) { |
|
310 name = serviceName.substring(serviceName.indexOf('/') + 1); |
|
311 } |
|
312 |
|
313 setName(name); |
|
314 } |
|
315 |
|
316 // |
|
317 // Private methods |
|
318 // |
|
319 |
|
320 private void serviceChanged() { |
|
321 setStatus(); |
|
322 setStatusText(); |
|
323 } |
|
324 } |