Project

General

Profile

Download (8.6 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.logging.log4j.LogManager;
22
import org.apache.logging.log4j.Logger;
23
import org.eclipse.jetty.plus.jndi.Resource;
24
import org.eclipse.jetty.server.handler.ContextHandler.Context;
25
import org.eclipse.jetty.util.component.LifeCycle;
26
import org.eclipse.jetty.util.component.LifeCycle.Listener;
27
import org.eclipse.jetty.webapp.WebAppContext;
28

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

    
31
public class CdmInstance implements Listener {
32

    
33
    private static final Logger logger = LogManager.getLogger();
34

    
35
    private WebAppContext webAppContext = null;
36

    
37
    private Configuration configuration;
38

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

    
42
    private Resource jndiDataSource;
43

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

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

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

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

    
63
    public void setStatus(Status status) {
64
        this.status = 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
    public void setConfiguration(Configuration configuration) {
84
        this.configuration = configuration;
85
    }
86

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

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

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

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

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

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

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

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

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

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

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

    
162
            getProblems().addAll(messages);
163

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

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

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

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

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

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

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

    
242
    public void unbindJndiDataSource() {
243

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

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

    
266

    
267

    
268
}
(1-1/7)