/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.camel.coap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.camel.Message; import org.eclipse.californium.core.CoapResource; import org.eclipse.californium.core.coap.CoAP.ResponseCode; import org.eclipse.californium.core.coap.MediaTypeRegistry; import org.eclipse.californium.core.coap.OptionSet; import org.eclipse.californium.core.network.Exchange; import org.eclipse.californium.core.server.resources.CoapExchange; import org.eclipse.californium.core.server.resources.Resource; final class CamelCoapResource extends CoapResource { private final Map<String, CoAPConsumer> consumers = new ConcurrentHashMap<>(); private final List<CamelCoapResource> possibles; CamelCoapResource(String name, CoAPConsumer consumer) { super(name); consumers.put(consumer.getCoapEndpoint().getCoapMethod(), consumer); possibles = null; } private CamelCoapResource(String name, List<CamelCoapResource> possibles) { super(name); this.possibles = possibles; } void addConsumer(CoAPConsumer consumer) { consumers.put(consumer.getCoapEndpoint().getCoapMethod(), consumer); } @Override public Resource getChild(String name) { if (possibles != null) { //FIXME - find which might work... } Resource child = super.getChild(name); if (child == null) { final List<CamelCoapResource> possibles = new LinkedList<>(); for (Resource r : getChildren()) { if (r.getName().startsWith("{") && r.getName().endsWith("}")) { possibles.add((CamelCoapResource)r); } } if (possibles.size() == 1) { return possibles.get(0); } if (!possibles.isEmpty()) { return new CamelCoapResource(name, possibles); } } return child; } @Override public void handleRequest(Exchange exchange) { org.apache.camel.Exchange camelExchange = null; CoAPConsumer consumer = null; if (possibles != null) { consumers.putAll(possibles.get(0).consumers); } CoapExchange cexchange = new CoapExchange(exchange, this); try { consumer = consumers.get(exchange.getRequest().getCode().name()); if (consumer == null) { consumer = consumers.get("*"); } camelExchange = consumer.getEndpoint().createExchange(); consumer.createUoW(camelExchange); OptionSet options = exchange.getRequest().getOptions(); for (String s : options.getUriQuery()) { int i = s.indexOf('='); if (i == -1) { camelExchange.getIn().setHeader(s, ""); } else { camelExchange.getIn().setHeader(s.substring(0, i), s.substring(i + 1)); } } if (options.hasContentFormat()) { String mt = MediaTypeRegistry.toString(options.getContentFormat()); camelExchange.getIn().setHeader(org.apache.camel.Exchange.CONTENT_TYPE, mt); } List<String> path = exchange.getRequest().getOptions().getUriPath(); LinkedList<Resource> resources = new LinkedList<>(); Resource r = this; while (r != null) { resources.push(r); r = r.getParent(); } if (resources.getFirst().getName().isEmpty()) { resources.removeFirst(); } int res = 0; while (!resources.isEmpty() && res < path.size()) { r = resources.removeFirst(); if (r.getName().charAt(0) == '{' && r.getName().charAt(r.getName().length() - 1) == '}') { String n = r.getName().substring(1, r.getName().length() - 1); camelExchange.getIn().setHeader(n, path.get(res)); } res++; } byte bytes[] = exchange.getCurrentRequest().getPayload(); camelExchange.getIn().setBody(bytes); consumer.getProcessor().process(camelExchange); Message target = camelExchange.hasOut() ? camelExchange.getOut() : camelExchange.getIn(); int format = MediaTypeRegistry.parse(target.getHeader(org.apache.camel.Exchange.CONTENT_TYPE, String.class)); cexchange.respond(ResponseCode.CONTENT, target.getBody(byte[].class), format); } catch (Exception e) { cexchange.respond(ResponseCode.INTERNAL_SERVER_ERROR, e.getMessage()); } finally { if (camelExchange != null) { consumer.doneUoW(camelExchange); } } } }