Project

General

Profile

Download (8.56 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2009 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * See LICENSE.TXT at the top of this package for the full license terms.
8
 */
9
package eu.etaxonomy.cdm.server.instance;
10

    
11
import java.lang.reflect.InvocationTargetException;
12
import java.sql.Connection;
13
import java.sql.SQLException;
14
import java.util.ArrayList;
15
import java.util.List;
16

    
17
import javax.naming.InitialContext;
18
import javax.naming.NamingException;
19
import javax.sql.DataSource;
20

    
21
import org.apache.log4j.Logger;
22
import org.eclipse.jetty.plus.jndi.Resource;
23
import org.eclipse.jetty.server.handler.ContextHandler.Context;
24
import org.eclipse.jetty.util.component.LifeCycle;
25
import org.eclipse.jetty.util.component.LifeCycle.Listener;
26
import org.eclipse.jetty.webapp.WebAppContext;
27

    
28
import com.mchange.v2.c3p0.DataSources;
29

    
30
public class CdmInstance implements Listener {
31

    
32
    private static final Logger logger = Logger.getLogger(CdmInstance.class);
33

    
34
    private WebAppContext webAppContext = null;
35

    
36
    private Configuration configuration;
37

    
38
    private List<String> problems;
39
    private Status status = Status.uninitialized;
40

    
41
    private Resource jndiDataSource;
42

    
43
    public CdmInstance(Configuration configuration) {
44
        this.configuration = configuration;
45
    }
46

    
47
    public List<String> getProblems() {
48
        if (problems == null) {
49
            problems = new ArrayList<>();
50
        }
51
        return problems;
52
    }
53

    
54
    public void clearProblems() {
55
        getProblems().clear();
56
    }
57

    
58
    public boolean onError() {
59
        return status.equals(Status.error);
60
    }
61

    
62
    public void setStatus(Status status) {
63
        this.status = status;
64
    }
65
    public Status getStatus() {
66
        return status;
67
    }
68

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

    
76
    /**
77
     * @return the configuration
78
     */
79
    public Configuration getConfiguration() {
80
        return configuration;
81
    }
82
    public void setConfiguration(Configuration configuration) {
83
        this.configuration = configuration;
84
    }
85

    
86
    /**
87
     * @return the webAppContext
88
     */
89
    public WebAppContext getWebAppContext() {
90
        return webAppContext;
91
    }
92
    public void setWebAppContext(WebAppContext webAppContext) {
93
        this.webAppContext = webAppContext;
94
    }
95

    
96
    public String getName() {
97
        return getConfiguration().getInstanceName();
98
    }
99

    
100
    /**
101
     * @param <T>
102
     * @param webAppContext
103
     * @param attributeName
104
     * @param type
105
     * @return
106
     */
107
    @SuppressWarnings("unchecked")
108
    private <T> T getServletContextAttribute(WebAppContext webAppContext, String attributeName, Class<T> type) {
109

    
110
        Context servletContext = webAppContext.getServletContext();
111
        Object value = servletContext.getInitParameter(attributeName);
112
        if (value != null && type.isAssignableFrom(value.getClass())) {
113

    
114
        }
115
        return (T) value;
116
    }
117

    
118
    @Override
119
    public void lifeCycleStopping(LifeCycle event) {
120
        logger.info("lifeCycleStopping");
121
        if(!getStatus().equals(Status.removed)){
122
            // never override Status.removed !!!
123
            setStatus(Status.stopping);
124
        }
125
    }
126

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

    
136
    @Override
137
    public void lifeCycleStarting(LifeCycle event) {
138
        logger.info("lifeCycleStarting");
139
        setStatus(Status.starting);
140
    }
141

    
142
    @SuppressWarnings("unchecked")
143
    @Override
144
    public void lifeCycleStarted(LifeCycle event) {
145
        logger.info("lifeCycleStarted");
146

    
147
        List<String> messages = getServletContextAttribute(webAppContext, SharedAttributes.ATTRIBUTE_ERROR_MESSAGES, List.class);
148
        String dataSourceName = getServletContextAttribute(webAppContext, SharedAttributes.ATTRIBUTE_DATASOURCE_NAME, String.class);
149

    
150
        if (messages != null && dataSourceName != null) {
151
            // Problems with instance
152
            Status errorStatus = Status.error;
153
            for(String message : messages){
154
                if(message.startsWith("Incompatible version")){
155
                    errorStatus = Status.incompatible_version;
156
                    break;
157
                }
158
            }
159
            setStatus(errorStatus);
160

    
161
            getProblems().addAll(messages);
162

    
163
            try {
164
                logger.warn("Stopping context '" + dataSourceName + "' due to errors reported in ServletContext");
165
                webAppContext.stop();
166
                setStatus(errorStatus);
167
            } catch (Exception e) {
168
                logger.error(e);
169
            }
170
        } else {
171
            // Instance is OK
172
            setStatus(Status.started);
173
        }
174
    }
175

    
176
    @Override
177
    public void lifeCycleFailure(LifeCycle event, Throwable cause) {
178
        logger.error("lifeCycleFailure");
179
        if(!getStatus().equals(Status.removed)){
180
            // never override Status.removed !!!
181
            setStatus(Status.error);
182
        }
183
        getProblems().add(cause.getMessage());
184
    }
185

    
186
    public void releaseWebAppContext() {
187
        webAppContext = null;
188
    }
189

    
190
    public boolean bindJndiDataSource() {
191
        try {
192
            Class<DataSource> datasourceClass = (Class<DataSource>) Thread.currentThread().getContextClassLoader().loadClass("com.mchange.v2.c3p0.ComboPooledDataSource");
193
            DataSource datasource = datasourceClass.newInstance();
194
            datasourceClass.getMethod("setDriverClass", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getDriverClass()});
195
            datasourceClass.getMethod("setJdbcUrl", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getDataSourceUrl()});
196
            datasourceClass.getMethod("setUser", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getUsername()});
197
            datasourceClass.getMethod("setPassword", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getPassword()});
198

    
199
            Connection connection = null;
200
            String sqlerror = null;
201
            try {
202
                connection = datasource.getConnection();
203
                connection.close();
204
            } catch (SQLException e) {
205
                sqlerror = "Can not establish connection to database " + configuration.getDataSourceUrl() + " [sql error code: "+ e.getSQLState() + "]";
206
                getProblems().add(sqlerror);
207
                setStatus(Status.error);
208
                if(connection !=  null){
209
                    try {connection.close();} catch (SQLException e1) { /* IGNORE */ }
210
                }
211
                logger.error(configuration.toString() + " has problem : "+ sqlerror );
212
            }
213

    
214
            if(!onError()){
215
                logger.info("binding jndi datasource at " + configuration.getJdbcJndiName() + " with " + configuration.getUsername() +"@"+ configuration.getDataSourceUrl());
216
                jndiDataSource = new Resource(configuration.getJdbcJndiName(), datasource);
217
                return true;
218
            }
219

    
220
        } catch (IllegalArgumentException e) {
221
            logger.error(e);
222
            e.printStackTrace();
223
        } catch (SecurityException e) {
224
            logger.error(e);
225
        } catch (ClassNotFoundException e) {
226
            logger.error(e);
227
        } catch (InstantiationException e) {
228
            logger.error(e);
229
        } catch (IllegalAccessException e) {
230
            logger.error(e);
231
        } catch (InvocationTargetException e) {
232
            logger.error(e);
233
        } catch (NoSuchMethodException e) {
234
            logger.error(e);
235
        } catch (NamingException e) {
236
            logger.error(e);
237
        }
238
        return false;
239
    }
240

    
241
    public void unbindJndiDataSource() {
242

    
243
        if(jndiDataSource == null) {
244
            return; // nothing to to
245
        }
246

    
247
        try {
248
            InitialContext ic = new InitialContext();
249
            Object o = ic.lookup(jndiDataSource.getJndiNameInScope());
250
            if(o instanceof DataSource) {
251
                DataSources.destroy((DataSource) o);
252
                logger.info("datasource for " + jndiDataSource.getJndiNameInScope() + " destroyed");
253
            }
254
        } catch (NamingException e) {
255
            logger.error(e);
256
        } catch (SQLException e) {
257
            logger.error(e);
258
        }
259
        if(jndiDataSource != null){
260
            jndiDataSource.release();
261
            jndiDataSource = null;
262
        }
263
    }
264

    
265

    
266

    
267
}
(1-1/7)