Project

General

Profile

Download (8.46 KB) Statistics
| Branch: | Tag: | Revision:
1
package eu.etaxonomy.cdm.server.instance;
2

    
3
import java.lang.reflect.InvocationTargetException;
4
import java.sql.Connection;
5
import java.sql.SQLException;
6
import java.util.ArrayList;
7
import java.util.List;
8

    
9
import javax.naming.InitialContext;
10
import javax.naming.NamingException;
11
import javax.sql.DataSource;
12

    
13
import org.apache.log4j.Logger;
14
import org.eclipse.jetty.plus.jndi.Resource;
15
import org.eclipse.jetty.server.handler.ContextHandler.Context;
16
import org.eclipse.jetty.util.component.LifeCycle;
17
import org.eclipse.jetty.util.component.LifeCycle.Listener;
18
import org.eclipse.jetty.webapp.WebAppContext;
19

    
20
import com.mchange.v2.c3p0.DataSources;
21

    
22

    
23
public class CdmInstance implements Listener {
24

    
25
    private static final Logger logger = Logger.getLogger(CdmInstance.class);
26

    
27
    private WebAppContext webAppContext = null;
28

    
29
    private Configuration configuration;
30

    
31
    private List<String> problems;
32
    private Status status = Status.uninitialized;
33

    
34
    private Resource jndiDataSource;
35

    
36
    public CdmInstance(Configuration configuration) {
37
        this.configuration = configuration;
38
    }
39

    
40
    public List<String> getProblems() {
41
        if (problems == null) {
42
            problems = new ArrayList<String>();
43
        }
44
        return problems;
45
    }
46

    
47
    public void clearProblems() {
48
        getProblems().clear();
49
    }
50

    
51
    public boolean onError() {
52
        return status.equals(Status.error);
53
    }
54

    
55
    /**
56
     * @param status
57
     *            the status to set
58
     */
59
    public void setStatus(Status status) {
60
        this.status = status;
61
    }
62

    
63
    /**
64
     * @return the status
65
     */
66
    public Status getStatus() {
67
        return status;
68
    }
69

    
70
    /**
71
     * @return true if status is not {@link Status#disabled}
72
     */
73
    public boolean isEnabled() {
74
        return !status.equals(Status.disabled);
75
    }
76

    
77
    /**
78
     * @return the configuration
79
     */
80
    public Configuration getConfiguration() {
81
        return configuration;
82
    }
83

    
84
    /**
85
     * @return the configuration
86
     */
87
    public void setConfiguration(Configuration configuration) {
88
        this.configuration = configuration;
89
    }
90

    
91
    /**
92
     * @return the webAppContext
93
     */
94
    public WebAppContext getWebAppContext() {
95
        return webAppContext;
96
    }
97

    
98
    /**
99
     * @return the webAppContext
100
     */
101
    public void setWebAppContext(WebAppContext webAppContext) {
102
        this.webAppContext = webAppContext;
103
    }
104

    
105
    public String getName() {
106
        return getConfiguration().getInstanceName();
107
    }
108

    
109
    /**
110
     * @param <T>
111
     * @param webAppContext
112
     * @param attributeName
113
     * @param type
114
     * @return
115
     */
116
    @SuppressWarnings("unchecked")
117
    private <T> T getServletContextAttribute(WebAppContext webAppContext, String attributeName, Class<T> type) {
118

    
119
        Context servletContext = webAppContext.getServletContext();
120
        Object value = servletContext.getInitParameter(attributeName);
121
        if (value != null && type.isAssignableFrom(value.getClass())) {
122

    
123
        }
124
        return (T) value;
125
    }
126

    
127
    @Override
128
    public void lifeCycleStopping(LifeCycle event) {
129
        logger.info("lifeCycleStopping");
130
        if(!getStatus().equals(Status.removed)){
131
            // never override Status.removed !!!
132
            setStatus(Status.stopping);
133
        }
134
    }
135

    
136
    @Override
137
    public void lifeCycleStopped(LifeCycle event) {
138
        logger.info("lifeCycleStopped");
139
        if(!getStatus().equals(Status.removed)){
140
            // never override Status.removed !!!
141
            setStatus(Status.stopped);
142
        }
143

    
144
    }
145

    
146
    @Override
147
    public void lifeCycleStarting(LifeCycle event) {
148
        logger.info("lifeCycleStarting");
149
        setStatus(Status.starting);
150
    }
151

    
152
    @SuppressWarnings("unchecked")
153
    @Override
154
    public void lifeCycleStarted(LifeCycle event) {
155
        logger.info("lifeCycleStarted");
156

    
157
        List<String> messages = getServletContextAttribute(webAppContext, SharedAttributes.ATTRIBUTE_ERROR_MESSAGES, List.class);
158
        String dataSourceName = getServletContextAttribute(webAppContext, SharedAttributes.ATTRIBUTE_DATASOURCE_NAME, String.class);
159

    
160
        if (messages != null && dataSourceName != null) {
161
            // Problems with instance
162
            Status errorStatus = Status.error;
163
            for(String message : messages){
164
                if(message.startsWith("Incompatible version")){
165
                    errorStatus = Status.incompatible_version;
166
                    break;
167
                }
168
            }
169
            setStatus(errorStatus);
170

    
171
            getProblems().addAll(messages);
172

    
173
            try {
174
                logger.warn("Stopping context '" + dataSourceName + "' due to errors reported in ServletContext");
175
                webAppContext.stop();
176
                setStatus(errorStatus);
177
            } catch (Exception e) {
178
                logger.error(e);
179
            }
180
        } else {
181
            // Instance is OK
182
            setStatus(Status.started);
183
        }
184
    }
185

    
186
    @Override
187
    public void lifeCycleFailure(LifeCycle event, Throwable cause) {
188
        logger.error("lifeCycleFailure");
189
        if(!getStatus().equals(Status.removed)){
190
            // never override Status.removed !!!
191
            setStatus(Status.error);
192
        }
193
        getProblems().add(cause.getMessage());
194
    }
195

    
196
    public void releaseWebAppContext() {
197
        webAppContext = null;
198
    }
199

    
200
    public boolean bindJndiDataSource() {
201
        try {
202
            Class<DataSource> dsCass = (Class<DataSource>) Thread.currentThread().getContextClassLoader().loadClass("com.mchange.v2.c3p0.ComboPooledDataSource");
203
            DataSource datasource = dsCass.newInstance();
204
            dsCass.getMethod("setDriverClass", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getDriverClass()});
205
            dsCass.getMethod("setJdbcUrl", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getDataSourceUrl()});
206
            dsCass.getMethod("setUser", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getUsername()});
207
            dsCass.getMethod("setPassword", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getPassword()});
208

    
209
            Connection connection = null;
210
            String sqlerror = null;
211
            try {
212
                connection = datasource.getConnection();
213
                connection.close();
214
            } catch (SQLException e) {
215
                sqlerror = "Can not establish connection to data base " + configuration.getDataSourceUrl() + " [sql error code: "+ e.getSQLState() + "]";
216
                getProblems().add(sqlerror);
217
                setStatus(Status.error);
218
                if(connection !=  null){
219
                    try {connection.close();} catch (SQLException e1) { /* IGNORE */ }
220
                }
221
                logger.error(configuration.toString() + " has problem : "+ sqlerror );
222
            }
223

    
224
            if(!onError()){
225
                logger.info("binding jndi datasource at " + configuration.getJdbcJndiName() + " with " + configuration.getUsername() +"@"+ configuration.getDataSourceUrl());
226
                jndiDataSource = new Resource(configuration.getJdbcJndiName(), datasource);
227
                return true;
228
            }
229

    
230
        } catch (IllegalArgumentException e) {
231
            logger.error(e);
232
            e.printStackTrace();
233
        } catch (SecurityException e) {
234
            logger.error(e);
235
        } catch (ClassNotFoundException e) {
236
            logger.error(e);
237
        } catch (InstantiationException e) {
238
            logger.error(e);
239
        } catch (IllegalAccessException e) {
240
            logger.error(e);
241
        } catch (InvocationTargetException e) {
242
            logger.error(e);
243
        } catch (NoSuchMethodException e) {
244
            logger.error(e);
245
        } catch (NamingException e) {
246
            logger.error(e);
247
        }
248
        return false;
249
    }
250

    
251
    public void unbindJndiDataSource() {
252

    
253
        if(jndiDataSource == null) {
254
            return; // nothing to to
255
        }
256

    
257
        try {
258
            InitialContext ic = new InitialContext();
259
            Object o = ic.lookup(jndiDataSource.getJndiNameInScope());
260
            if(o instanceof DataSource) {
261
                DataSources.destroy((DataSource) o);
262
                logger.info("datasource for " + jndiDataSource.getJndiNameInScope() + " destroyed");
263
            }
264
        } catch (NamingException e) {
265
            logger.error(e);
266
        } catch (SQLException e) {
267
            logger.error(e);
268
        }
269
        if(jndiDataSource != null){
270
            jndiDataSource.release();
271
            jndiDataSource = null;
272
        }
273
    }
274

    
275

    
276

    
277
}
(1-1/7)