001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.impl;
018
019import java.util.ArrayList;
020import java.util.Date;
021import java.util.HashMap;
022import java.util.List;
023import java.util.Map;
024
025import org.apache.camel.Endpoint;
026import org.apache.camel.Route;
027import org.apache.camel.Service;
028import org.apache.camel.spi.RouteContext;
029import org.apache.camel.support.ServiceSupport;
030import org.apache.camel.util.TimeUtils;
031
032/**
033 * Default implementation of {@link Route}.
034 * <p/>
035 * Use the API from {@link org.apache.camel.CamelContext} to control the lifecycle of a route,
036 * such as starting and stopping using the {@link org.apache.camel.CamelContext#startRoute(String)}
037 * and {@link org.apache.camel.CamelContext#stopRoute(String)} methods.
038 *
039 * @version 
040 */
041public abstract class DefaultRoute extends ServiceSupport implements Route {
042
043    private final Endpoint endpoint;
044    private final Map<String, Object> properties = new HashMap<>();
045    private final List<Service> services = new ArrayList<>();
046    private final RouteContext routeContext;
047    private Date startDate;
048
049    public DefaultRoute(RouteContext routeContext, Endpoint endpoint) {
050        this.routeContext = routeContext;
051        this.endpoint = endpoint;
052    }
053
054    public DefaultRoute(RouteContext routeContext, Endpoint endpoint, Service... services) {
055        this(routeContext, endpoint);
056        for (Service service : services) {
057            addService(service);
058        }
059    }
060
061    @Override
062    public String toString() {
063        return "Route " + getId();
064    }
065
066    public String getId() {
067        return (String) properties.get(Route.ID_PROPERTY);
068    }
069
070    public String getGroup() {
071        return (String) properties.get(Route.GROUP_PROPERTY);
072    }
073
074    public String getUptime() {
075        long delta = getUptimeMillis();
076        if (delta == 0) {
077            return "";
078        }
079        return TimeUtils.printDuration(delta);
080    }
081
082    public long getUptimeMillis() {
083        if (startDate == null) {
084            return 0;
085        }
086        return new Date().getTime() - startDate.getTime();
087    }
088
089    public Endpoint getEndpoint() {
090        return endpoint;
091    }
092
093    public RouteContext getRouteContext() {
094        return routeContext;
095    }
096
097    public Map<String, Object> getProperties() {
098        return properties;
099    }
100
101    public String getDescription() {
102        Object value = properties.get(Route.DESCRIPTION_PROPERTY);
103        return value != null ? value.toString() : null;
104    }
105
106    public void onStartingServices(List<Service> services) throws Exception {
107        addServices(services);
108    }
109
110    public List<Service> getServices() {
111        return services;
112    }
113
114    public void addService(Service service) {
115        if (!services.contains(service)) {
116            services.add(service);
117        }
118    }
119
120    public void warmUp() {
121        getServices().clear();
122    }
123
124    /**
125     * Do not invoke this method directly, use {@link org.apache.camel.CamelContext#startRoute(String)} to start a route.
126     */
127    @Override
128    public void start() throws Exception {
129        super.start();
130    }
131
132    /**
133     * Do not invoke this method directly, use {@link org.apache.camel.CamelContext#stopRoute(String)} to stop a route.
134     */
135    @Override
136    public void stop() throws Exception {
137        super.stop();
138    }
139
140    /**
141     * Strategy method to allow derived classes to lazily load services for the route
142     */
143    protected void addServices(List<Service> services) throws Exception {
144    }
145
146    protected void doStart() throws Exception {
147        startDate = new Date();
148    }
149
150    protected void doStop() throws Exception {
151        // and clear start date
152        startDate = null;
153    }
154
155    @Override
156    protected void doShutdown() throws Exception {
157        // and clear start date
158        startDate = null;
159        // clear services when shutting down
160        services.clear();
161    }
162}