protected GenericFileEndpoint<File> buildFileEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { // the starting directory must be a static (not containing dynamic expressions) if (StringHelper.hasStartToken(remaining, "simple")) { throw new IllegalArgumentException("Invalid directory: " + remaining + ". Dynamic expressions with ${ } placeholders is not allowed." + " Use the fileName option to set the dynamic expression."); } File file = new File(remaining); FileEndpoint result = new FileEndpoint(uri, this); result.setFile(file); GenericFileConfiguration config = new GenericFileConfiguration(); config.setDirectory(FileUtil.isAbsolute(file) ? file.getAbsolutePath() : file.getPath()); result.setConfiguration(config); return result; }
/** * Strategy to configure the move, preMove, or moveExisting option based on a String input. * * @param expression the original string input * @return configured string or the original if no modifications is needed */ protected String configureMoveOrPreMoveExpression(String expression) { // if the expression already have ${ } placeholders then pass it unmodified if (StringHelper.hasStartToken(expression, "simple")) { return expression; } // remove trailing slash expression = FileUtil.stripTrailingSeparator(expression); StringBuilder sb = new StringBuilder(); // if relative then insert start with the parent folder if (!isAbsolute(expression)) { sb.append("${file:parent}"); sb.append(getFileSeparator()); } // insert the directory the end user provided sb.append(expression); // append only the filename (file:name can contain a relative path, so we must use onlyname) sb.append(getFileSeparator()); sb.append("${file:onlyname}"); return sb.toString(); }
public void testManagedCamelContextCreateRouteStaticEndpointJson() throws Exception { // JMX tests dont work well on AIX CI servers (hangs them) if (isPlatform("aix")) { return; } MBeanServer mbeanServer = getMBeanServer(); ObjectName on = ObjectName.getInstance("org.apache.camel:context=19-camel-1,type=context,name=\"camel-1\""); // get the json String json = (String) mbeanServer.invoke(on, "createRouteStaticEndpointJson", null, null); assertNotNull(json); assertEquals(7, StringHelper.countChar(json, '{')); assertEquals(7, StringHelper.countChar(json, '}')); assertTrue(json.contains("{ \"uri\": \"direct://start\" }")); assertTrue(json.contains("{ \"uri\": \"direct://foo\" }")); }
@Converter public static BoxFileUploadRequestObject toBox(byte[] data, Exchange exchange) throws Exception { String folderId = ROOT_FOLDER; // fileName is generated from exchange.in id by default String fileName; if (exchange != null && exchange.getIn() != null) { // get folderId folderId = exchange.getIn().getHeader(PROPERTY_FOLDER_ID_DELIMITED, folderId, String.class); // support camel case CamelBoxFolderId folderId = exchange.getIn().getHeader(PROPERTY_FOLDER_ID, folderId, String.class); fileName = exchange.getIn().getHeader(Exchange.FILE_NAME, StringHelper.sanitize(exchange.getIn().getMessageId()), String.class); } else { synchronized (BoxConverter.class) { fileName = "CamelBox" + ISO8601.format(new Date()) + ".bin"; } } InputStream is = new ByteArrayInputStream(data); return BoxFileUploadRequestObject.uploadFileRequestObject(folderId, fileName, is); }
@Override public void marshal(final Exchange exchange, final Object graph, final OutputStream stream) throws Exception { String filename = exchange.getIn().getHeader(FILE_NAME, String.class); if (filename == null) { // generate the file name as the camel file component would do filename = StringHelper.sanitize(exchange.getIn().getMessageId()); } else { filename = Paths.get(filename).getFileName().toString(); // remove any path elements } ZipOutputStream zos = new ZipOutputStream(stream); zos.putNextEntry(new ZipEntry(filename)); InputStream is = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, exchange, graph); try { IOHelper.copy(is, zos); } finally { IOHelper.close(is, zos); } String newFilename = filename + ".zip"; exchange.getOut().setHeader(FILE_NAME, newFilename); }
@Test public void testCreateAndGetOrder() throws Exception { String json = "{\"partName\":\"motor\",\"amount\":1,\"customerName\":\"honda\"}"; log.info("Sending order using json payload: {}", json); // use http component to send the order String id = template.requestBody("http://localhost:8080/orders", json, String.class); assertNotNull(id); log.info("Created new order with id " + id); // should create a new order with id 3 (json format so its enclosed in quotes) assertEquals("\"3\"", id); // remove quoutes id = StringHelper.removeQuotes(id); // use http component to get the order String response = template.requestBody("http://localhost:8080/orders/" + id, null, String.class); log.info("Response: {}", response); }
@Override public void doStart() throws Exception { // required options StringHelper.notEmpty(scheme, "scheme"); StringHelper.notEmpty(hostname, "hostname"); super.doStart(); }
private static String buildUrl(String scheme, String hostname, Object port, String path, String uri) { // build together from component level and given uri that has additional context path to append String build = scheme + "://" + hostname; if (port != null) { build += ":" + port; } if (path != null) { build = FileUtil.stripTrailingSeparator(build); build += "/" + path; } String query = null; if (uri != null && uri.contains("?")) { query = StringHelper.after(uri, "?"); uri = StringHelper.before(uri, "?"); uri = StringHelper.after(uri, "://"); } // remaining is to be appending if (uri != null) { build = FileUtil.stripTrailingSeparator(build); build += "/" + uri; } if (query != null) { build += "?" + query; } return build; }
private Map<String, String> extractComponentDefaultValues(List<String> lines) { Map<String, String> answer = new LinkedHashMap<>(); // extract the default options boolean found = false; for (String line : lines) { line = line.trim(); if (line.startsWith("\"componentValues\":")) { found = true; } else if (line.startsWith("}")) { found = false; } else if (found) { // "showAll":"true", int pos = line.indexOf(':'); String key = line.substring(0, pos); String value = line.substring(pos + 1); if (value.endsWith(",")) { value = value.substring(0, value.length() - 1); } key = StringHelper.removeLeadingAndEndingQuotes(key); value = StringHelper.removeLeadingAndEndingQuotes(value); answer.put(key, value); } } return answer; }
private Map<String, String> extractEndpointDefaultValues(List<String> lines) { Map<String, String> answer = new LinkedHashMap<>(); // extract the default options boolean found = false; for (String line : lines) { line = line.trim(); if (line.startsWith("\"endpointValues\":")) { found = true; } else if (line.startsWith("}")) { found = false; } else if (found) { // "showAll":"true", int pos = line.indexOf(':'); String key = line.substring(0, pos); String value = line.substring(pos + 1); if (value.endsWith(",")) { value = value.substring(0, value.length() - 1); } key = StringHelper.removeLeadingAndEndingQuotes(key); value = StringHelper.removeLeadingAndEndingQuotes(value); answer.put(key, value); } } return answer; }
/** * Returns Simple expression or fallback to Constant expression if expression str is not Simple expression. */ public static Expression parseSimpleOrFallbackToConstantExpression(String str, CamelContext camelContext) { if (StringHelper.hasStartToken(str, "simple")) { return camelContext.resolveLanguage("simple").createExpression(str); } return constantExpression(str); }
/** * Creates the associated name of the done file based on the given file name. * <p/> * This method should only be invoked if a done filename property has been set on this endpoint. * * @param fileName the file name * @return name of the associated done file name */ protected String createDoneFileName(String fileName) { String pattern = getDoneFileName(); ObjectHelper.notEmpty(pattern, "doneFileName", pattern); // we only support ${file:name} or ${file:name.noext} as dynamic placeholders for done files String path = FileUtil.onlyPath(fileName); String onlyName = FileUtil.stripPath(fileName); pattern = pattern.replaceFirst("\\$\\{file:name\\}", onlyName); pattern = pattern.replaceFirst("\\$simple\\{file:name\\}", onlyName); pattern = pattern.replaceFirst("\\$\\{file:name.noext\\}", FileUtil.stripExt(onlyName)); pattern = pattern.replaceFirst("\\$simple\\{file:name.noext\\}", FileUtil.stripExt(onlyName)); // must be able to resolve all placeholders supported if (StringHelper.hasStartToken(pattern, "simple")) { throw new ExpressionIllegalSyntaxException(fileName + ". Cannot resolve reminder: " + pattern); } String answer = pattern; if (ObjectHelper.isNotEmpty(path) && ObjectHelper.isNotEmpty(pattern)) { // done file must always be in same directory as the real file name answer = path + getFileSeparator() + pattern; } if (getConfiguration().needToNormalize()) { // must normalize path to cater for Windows and other OS answer = FileUtil.normalizePath(answer); } return answer; }
/** * Is the given file a done file? * <p/> * This method should only be invoked if a done filename property has been set on this endpoint. * * @param fileName the file name * @return <tt>true</tt> if its a done file, <tt>false</tt> otherwise */ protected boolean isDoneFile(String fileName) { String pattern = getDoneFileName(); ObjectHelper.notEmpty(pattern, "doneFileName", pattern); if (!StringHelper.hasStartToken(pattern, "simple")) { // no tokens, so just match names directly return pattern.equals(fileName); } // the static part of the pattern, is that a prefix or suffix? // its a prefix if ${ start token is not at the start of the pattern boolean prefix = pattern.indexOf("${") > 0; // remove dynamic parts of the pattern so we only got the static part left pattern = pattern.replaceFirst("\\$\\{file:name\\}", ""); pattern = pattern.replaceFirst("\\$simple\\{file:name\\}", ""); pattern = pattern.replaceFirst("\\$\\{file:name.noext\\}", ""); pattern = pattern.replaceFirst("\\$simple\\{file:name.noext\\}", ""); // must be able to resolve all placeholders supported if (StringHelper.hasStartToken(pattern, "simple")) { throw new ExpressionIllegalSyntaxException(fileName + ". Cannot resolve reminder: " + pattern); } if (prefix) { return fileName.startsWith(pattern); } else { return fileName.endsWith(pattern); } }
public void testManagedCamelContextExplainEndpointUriFalse() throws Exception { // JMX tests dont work well on AIX CI servers (hangs them) if (isPlatform("aix")) { return; } MBeanServer mbeanServer = getMBeanServer(); ObjectName on = ObjectName.getInstance("org.apache.camel:context=19-camel-1,type=context,name=\"camel-1\""); // get the json String json = (String) mbeanServer.invoke(on, "explainEndpointJson", new Object[]{"log:foo?groupDelay=2000&groupSize=5", false}, new String[]{"java.lang.String", "boolean"}); assertNotNull(json); // the loggerName option should come before the groupDelay option int pos = json.indexOf("loggerName"); int pos2 = json.indexOf("groupDelay"); assertTrue("LoggerName should come before groupDelay", pos < pos2); assertEquals(6, StringHelper.countChar(json, '{')); assertEquals(6, StringHelper.countChar(json, '}')); assertTrue(json.contains("\"scheme\": \"log\"")); assertTrue(json.contains("\"label\": \"core,monitoring\"")); assertTrue(json.contains("\"loggerName\": { \"kind\": \"path\", \"group\": \"producer\", \"required\": \"true\"")); assertTrue(json.contains("\"groupSize\": { \"kind\": \"parameter\", \"group\": \"producer\", \"type\": \"integer\"," + " \"javaType\": \"java.lang.Integer\", \"deprecated\": \"false\", \"value\": \"5\"")); // and we should also have the javadoc documentation assertTrue(json.contains("Set the initial delay for stats (in millis)")); }
public void testManagedCamelContextExplainEndpointUriTrue() throws Exception { // JMX tests dont work well on AIX CI servers (hangs them) if (isPlatform("aix")) { return; } MBeanServer mbeanServer = getMBeanServer(); ObjectName on = ObjectName.getInstance("org.apache.camel:context=19-camel-1,type=context,name=\"camel-1\""); // get the json String json = (String) mbeanServer.invoke(on, "explainEndpointJson", new Object[]{"log:foo?groupDelay=2000&groupSize=5", true}, new String[]{"java.lang.String", "boolean"}); assertNotNull(json); // the loggerName option should come before the groupDelay option int pos = json.indexOf("loggerName"); int pos2 = json.indexOf("groupDelay"); assertTrue("LoggerName should come before groupDelay", pos < pos2); assertEquals(30, StringHelper.countChar(json, '{')); assertEquals(30, StringHelper.countChar(json, '}')); assertTrue(json.contains("\"scheme\": \"log\"")); assertTrue(json.contains("\"label\": \"core,monitoring\"")); assertTrue(json.contains("\"loggerName\": { \"kind\": \"path\", \"group\": \"producer\", \"required\": \"true\"")); assertTrue(json.contains("\"groupSize\": { \"kind\": \"parameter\", \"group\": \"producer\", \"type\": \"integer\"," + " \"javaType\": \"java.lang.Integer\", \"deprecated\": \"false\", \"value\": \"5\"")); // and we should also have the javadoc documentation assertTrue(json.contains("Set the initial delay for stats (in millis)")); }
public void testManagedCamelContextCreateRouteStaticEndpointJson() throws Exception { // JMX tests dont work well on AIX CI servers (hangs them) if (isPlatform("aix")) { return; } MBeanServer mbeanServer = getMBeanServer(); ObjectName on = ObjectName.getInstance("org.apache.camel:context=20-camel-1,type=context,name=\"camel-1\""); // get the json String json = (String) mbeanServer.invoke(on, "createRouteStaticEndpointJson", null, null); assertNotNull(json); assertEquals(2, StringHelper.countChar(json, '{')); assertEquals(2, StringHelper.countChar(json, '}')); }
@Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start") .setHeader("foo", method(StringHelper.class, "removeLeadingAndEndingQuotes(${header.bar})")) .to("mock:result"); } }; }
@Override public void marshal(final Exchange exchange, final Object graph, final OutputStream stream) throws Exception { String filename = exchange.getIn().getHeader(FILE_NAME, String.class); Long filelength = exchange.getIn().getHeader(FILE_LENGTH, Long.class); if (filename == null) { // generate the file name as the camel file component would do filename = StringHelper.sanitize(exchange.getIn().getMessageId()); } else { filename = Paths.get(filename).getFileName().toString(); // remove any path elements } TarArchiveOutputStream tos = new TarArchiveOutputStream(stream); tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); tos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX); InputStream is = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, graph); if (filelength == null) { filelength = (long) is.available(); } TarArchiveEntry entry = new TarArchiveEntry(filename); entry.setSize(filelength); tos.putArchiveEntry(entry); try { IOHelper.copy(is, tos); } finally { tos.closeArchiveEntry(); IOHelper.close(is, tos); } String newFilename = filename + ".tar"; exchange.getOut().setHeader(FILE_NAME, newFilename); }
@Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("jetty://http://localhost:9080/service/order") .transform().message(m -> "ID=" + m.getHeader("id")) .to("mock:miranda") .transform().body(String.class, b -> StringHelper.after(b, "STATUS=")); } }; }
/** * Filters the given list of packages and returns an array of <b>only</b> package names. * <p/> * This implementation will check the given list of packages, and if it contains a class name, * that class will be loaded directly and added to the list of classes. This optimizes the * type converter to avoid excessive file scanning for .class files. * * @param resolver the class resolver * @param packageNames the package names * @param classes to add loaded @Converter classes * @return the filtered package names */ protected String[] filterPackageNamesOnly(PackageScanClassResolver resolver, String[] packageNames, Set<Class<?>> classes) { if (packageNames == null || packageNames.length == 0) { return packageNames; } // optimize for CorePackageScanClassResolver if (resolver.getClassLoaders().isEmpty()) { return packageNames; } // the filtered packages to return List<String> packages = new ArrayList<String>(); // try to load it as a class first for (String name : packageNames) { // must be a FQN class name by having an upper case letter if (StringHelper.isClassName(name)) { Class<?> clazz = null; for (ClassLoader loader : resolver.getClassLoaders()) { try { clazz = ObjectHelper.loadClass(name, loader); LOG.trace("Loaded {} as class {}", name, clazz); classes.add(clazz); // class founder, so no need to load it with another class loader break; } catch (Throwable e) { // do nothing here } } if (clazz == null) { // ignore as its not a class (will be package scan afterwards) packages.add(name); } } else { // ignore as its not a class (will be package scan afterwards) packages.add(name); } } // return the packages which is not FQN classes return packages.toArray(new String[packages.size()]); }
private Object lookupResult(Exchange exchange, String key, Object result, boolean nullSafe, String ognlPath, Object bean) { ObjectHelper.notEmpty(key, "key", "in Simple language ognl path: " + ognlPath); // trim key key = key.trim(); // remove any enclosing quotes key = StringHelper.removeLeadingAndEndingQuotes(key); // try map first Map<?, ?> map = exchange.getContext().getTypeConverter().convertTo(Map.class, result); if (map != null) { return map.get(key); } // special for list is last keyword Integer num = exchange.getContext().getTypeConverter().tryConvertTo(Integer.class, key); boolean checkList = key.startsWith("last") || num != null; if (checkList) { List<?> list = exchange.getContext().getTypeConverter().convertTo(List.class, result); if (list != null) { if (key.startsWith("last")) { num = list.size() - 1; // maybe its an expression to subtract a number after last String after = ObjectHelper.after(key, "-"); if (after != null) { Integer redux = exchange.getContext().getTypeConverter().tryConvertTo(Integer.class, after.trim()); if (redux != null) { num -= redux; } else { throw new ExpressionIllegalSyntaxException(key); } } } if (num != null && num >= 0 && list.size() > num - 1) { return list.get(num); } if (!nullSafe) { // not null safe then its mandatory so thrown out of bounds exception throw new IndexOutOfBoundsException("Index: " + num + ", Size: " + list.size() + " out of bounds with List from bean: " + bean + "using OGNL path [" + ognlPath + "]"); } } } if (!nullSafe) { throw new IndexOutOfBoundsException("Key: " + key + " not found in bean: " + bean + " of type: " + ObjectHelper.classCanonicalName(bean) + " using OGNL path [" + ognlPath + "]"); } else { // null safe so we can return null return null; } }
/** * Determines and maps the given value is valid according to the supported * values by the bean component. * * @param value the value * @return the parameter type the given value is being mapped as, or <tt>null</tt> if not valid. */ public static Class<?> getValidParameterType(String value) { if (ObjectHelper.isEmpty(value)) { return null; } // trim value value = value.trim(); // single quoted is valid if (value.startsWith("'") && value.endsWith("'")) { return String.class; } // double quoted is valid if (value.startsWith("\"") && value.endsWith("\"")) { return String.class; } // true or false is valid (boolean) if (value.equals("true") || value.equals("false")) { return Boolean.class; } // null is valid (to force a null value) if (value.equals("null")) { return Object.class; } // simple language tokens is valid if (StringHelper.hasStartToken(value, "simple")) { return Object.class; } // numeric is valid boolean numeric = true; for (char ch : value.toCharArray()) { if (!Character.isDigit(ch)) { numeric = false; break; } } if (numeric) { return Number.class; } // not valid return null; }
public String encodeKey(String key) { String answer = StringHelper.replaceAll(key, DOT, DOT_REPLACEMENT); answer = StringHelper.replaceAll(answer, HYPHEN, HYPHEN_REPLACEMENT); return answer; }
public String decodeKey(String key) { String answer = StringHelper.replaceAll(key, DOT_REPLACEMENT, DOT); answer = StringHelper.replaceAll(answer, HYPHEN_REPLACEMENT, HYPHEN); return answer; }
private StringBuilder newFileName() { StringBuilder actualPath = new StringBuilder(hdfsPath); actualPath.append(StringHelper.sanitize(getEndpoint().getCamelContext().getUuidGenerator().generateUuid())); return actualPath; }
/** * Converts the given snmp pdu to a String body. * * @param pdu the snmp pdu * @return the text content */ @Converter public static String toString(PDU pdu) { // the output buffer StringBuilder sb = new StringBuilder(); // prepare the header if (pdu.getType() == PDU.V1TRAP) { sb.append("<" + SNMP_TAG + " messageType=\"v1\">"); } else { sb.append(SNMP_TAG_OPEN); } // Extract SNMPv1 specific variables if (pdu.getType() == PDU.V1TRAP) { PDUv1 v1pdu = (PDUv1) pdu; entryAppend(sb, "enterprise", v1pdu.getEnterprise().toString()); entryAppend(sb, "agent-addr", v1pdu.getAgentAddress().toString()); entryAppend(sb, "generic-trap", Integer.toString(v1pdu.getGenericTrap())); entryAppend(sb, "specific-trap", Integer.toString(v1pdu.getSpecificTrap())); entryAppend(sb, "time-stamp", Long.toString(v1pdu.getTimestamp())); } // now loop all variables of the response for (Object o : pdu.getVariableBindings()) { VariableBinding b = (VariableBinding)o; sb.append(ENTRY_TAG_OPEN); sb.append(OID_TAG_OPEN); sb.append(b.getOid().toString()); sb.append(OID_TAG_CLOSE); sb.append(VALUE_TAG_OPEN); sb.append(StringHelper.xmlEncode(b.getVariable().toString())); sb.append(VALUE_TAG_CLOSE); sb.append(ENTRY_TAG_CLOSE); } // prepare the footer sb.append(SNMP_TAG_CLOSE); return sb.toString(); }
public void process(Exchange exchange) throws Exception { String body = exchange.getIn().getBody(String.class); String reply = StringHelper.after(body, "STATUS="); exchange.getIn().setBody(reply); }
/** * Return the file name that will be auto-generated for the given message if * none is provided */ public String getGeneratedFileName(Message message) { return StringHelper.sanitize(message.getMessageId()); }