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.LinkedHashMap; 021import java.util.List; 022import java.util.Map; 023 024import org.apache.camel.CamelContext; 025import org.apache.camel.CamelContextAware; 026import org.apache.camel.Consumer; 027import org.apache.camel.Route; 028import org.apache.camel.Service; 029import org.apache.camel.ServiceStatus; 030import org.apache.camel.StatefulService; 031import org.apache.camel.StaticService; 032import org.apache.camel.spi.RestRegistry; 033import org.apache.camel.support.LifecycleStrategySupport; 034import org.apache.camel.support.ServiceSupport; 035import org.apache.camel.util.ObjectHelper; 036 037public class DefaultRestRegistry extends ServiceSupport implements StaticService, RestRegistry, CamelContextAware { 038 039 private CamelContext camelContext; 040 private final Map<Consumer, RestService> registry = new LinkedHashMap<Consumer, RestService>(); 041 042 public void addRestService(Consumer consumer, String url, String baseUrl, String basePath, String uriTemplate, String method, 043 String consumes, String produces, String inType, String outType, String routeId, String description) { 044 RestServiceEntry entry = new RestServiceEntry(consumer, url, baseUrl, basePath, uriTemplate, method, consumes, produces, inType, outType, routeId, description); 045 registry.put(consumer, entry); 046 } 047 048 public void removeRestService(Consumer consumer) { 049 registry.remove(consumer); 050 } 051 052 @Override 053 public List<RestRegistry.RestService> listAllRestServices() { 054 return new ArrayList<RestService>(registry.values()); 055 } 056 057 @Override 058 public int size() { 059 return registry.size(); 060 } 061 062 public CamelContext getCamelContext() { 063 return camelContext; 064 } 065 066 public void setCamelContext(CamelContext camelContext) { 067 this.camelContext = camelContext; 068 } 069 070 @Override 071 protected void doStart() throws Exception { 072 ObjectHelper.notNull(camelContext, "camelContext", this); 073 // add a lifecycle so we can keep track when consumers is being removed, so we can unregister them from our registry 074 camelContext.addLifecycleStrategy(new RemoveRestServiceLifecycleStrategy()); 075 } 076 077 @Override 078 protected void doStop() throws Exception { 079 registry.clear(); 080 } 081 082 /** 083 * Represents a rest service 084 */ 085 private final class RestServiceEntry implements RestService { 086 087 private final Consumer consumer; 088 private final String url; 089 private final String baseUrl; 090 private final String basePath; 091 private final String uriTemplate; 092 private final String method; 093 private final String consumes; 094 private final String produces; 095 private final String inType; 096 private final String outType; 097 private final String routeId; 098 private final String description; 099 100 private RestServiceEntry(Consumer consumer, String url, String baseUrl, String basePath, String uriTemplate, String method, 101 String consumes, String produces, String inType, String outType, String routeId, String description) { 102 this.consumer = consumer; 103 this.url = url; 104 this.baseUrl = baseUrl; 105 this.basePath = basePath; 106 this.uriTemplate = uriTemplate; 107 this.method = method; 108 this.consumes = consumes; 109 this.produces = produces; 110 this.inType = inType; 111 this.outType = outType; 112 this.routeId = routeId; 113 this.description = description; 114 } 115 116 public Consumer getConsumer() { 117 return consumer; 118 } 119 120 public String getUrl() { 121 return url; 122 } 123 124 public String getBaseUrl() { 125 return baseUrl; 126 } 127 128 public String getBasePath() { 129 return basePath; 130 } 131 132 public String getUriTemplate() { 133 return uriTemplate; 134 } 135 136 public String getMethod() { 137 return method; 138 } 139 140 public String getConsumes() { 141 return consumes; 142 } 143 144 public String getProduces() { 145 return produces; 146 } 147 148 public String getInType() { 149 return inType; 150 } 151 152 public String getOutType() { 153 return outType; 154 } 155 156 public String getState() { 157 // must use String type to be sure remote JMX can read the attribute without requiring Camel classes. 158 ServiceStatus status = null; 159 if (consumer instanceof StatefulService) { 160 status = ((StatefulService) consumer).getStatus(); 161 } 162 // if no status exists then its stopped 163 if (status == null) { 164 status = ServiceStatus.Stopped; 165 } 166 return status.name(); 167 } 168 169 public String getRouteId() { 170 return routeId; 171 } 172 173 public String getDescription() { 174 return description; 175 } 176 } 177 178 /** 179 * A {@link org.apache.camel.spi.LifecycleStrategy} that keeps track when a {@link Consumer} is removed 180 * and automatic un-register it from this REST registry. 181 */ 182 private final class RemoveRestServiceLifecycleStrategy extends LifecycleStrategySupport { 183 184 @Override 185 public void onServiceRemove(CamelContext context, Service service, Route route) { 186 super.onServiceRemove(context, service, route); 187 188 // if its a consumer then de-register it from the rest registry 189 if (service instanceof Consumer) { 190 removeRestService((Consumer) service); 191 } 192 } 193 } 194}