Search in sources :

Example 1 with TeeInputStream

use of org.apache.commons.io.input.TeeInputStream in project nifi by apache.

the class InvokeHTTP method onTrigger.

@Override
public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
    OkHttpClient okHttpClient = okHttpClientAtomicReference.get();
    FlowFile requestFlowFile = session.get();
    // Checking to see if the property to put the body of the response in an attribute was set
    boolean putToAttribute = context.getProperty(PROP_PUT_OUTPUT_IN_ATTRIBUTE).isSet();
    if (requestFlowFile == null) {
        if (context.hasNonLoopConnection()) {
            return;
        }
        String request = context.getProperty(PROP_METHOD).evaluateAttributeExpressions().getValue().toUpperCase();
        if ("POST".equals(request) || "PUT".equals(request) || "PATCH".equals(request)) {
            return;
        } else if (putToAttribute) {
            requestFlowFile = session.create();
        }
    }
    // Setting some initial variables
    final int maxAttributeSize = context.getProperty(PROP_PUT_ATTRIBUTE_MAX_LENGTH).asInteger();
    final ComponentLog logger = getLogger();
    // log ETag cache metrics
    final boolean eTagEnabled = context.getProperty(PROP_USE_ETAG).asBoolean();
    if (eTagEnabled && logger.isDebugEnabled()) {
        final Cache cache = okHttpClient.cache();
        logger.debug("OkHttp ETag cache metrics :: Request Count: {} | Network Count: {} | Hit Count: {}", new Object[] { cache.requestCount(), cache.networkCount(), cache.hitCount() });
    }
    // Every request/response cycle has a unique transaction id which will be stored as a flowfile attribute.
    final UUID txId = UUID.randomUUID();
    FlowFile responseFlowFile = null;
    try {
        // read the url property from the context
        final String urlstr = trimToEmpty(context.getProperty(PROP_URL).evaluateAttributeExpressions(requestFlowFile).getValue());
        final URL url = new URL(urlstr);
        Request httpRequest = configureRequest(context, session, requestFlowFile, url);
        // log request
        logRequest(logger, httpRequest);
        // emit send provenance event if successfully sent to the server
        if (httpRequest.body() != null) {
            session.getProvenanceReporter().send(requestFlowFile, url.toExternalForm(), true);
        }
        final long startNanos = System.nanoTime();
        Response responseHttp = okHttpClient.newCall(httpRequest).execute();
        // output the raw response headers (DEBUG level only)
        logResponse(logger, url, responseHttp);
        // store the status code and message
        int statusCode = responseHttp.code();
        String statusMessage = responseHttp.message();
        if (statusCode == 0) {
            throw new IllegalStateException("Status code unknown, connection hasn't been attempted.");
        }
        // Create a map of the status attributes that are always written to the request and response FlowFiles
        Map<String, String> statusAttributes = new HashMap<>();
        statusAttributes.put(STATUS_CODE, String.valueOf(statusCode));
        statusAttributes.put(STATUS_MESSAGE, statusMessage);
        statusAttributes.put(REQUEST_URL, url.toExternalForm());
        statusAttributes.put(TRANSACTION_ID, txId.toString());
        if (requestFlowFile != null) {
            requestFlowFile = session.putAllAttributes(requestFlowFile, statusAttributes);
        }
        // If the property to add the response headers to the request flowfile is true then add them
        if (context.getProperty(PROP_ADD_HEADERS_TO_REQUEST).asBoolean() && requestFlowFile != null) {
            // write the response headers as attributes
            // this will overwrite any existing flowfile attributes
            requestFlowFile = session.putAllAttributes(requestFlowFile, convertAttributesFromHeaders(url, responseHttp));
        }
        boolean outputBodyToRequestAttribute = (!isSuccess(statusCode) || putToAttribute) && requestFlowFile != null;
        boolean outputBodyToResponseContent = (isSuccess(statusCode) && !putToAttribute) || context.getProperty(PROP_OUTPUT_RESPONSE_REGARDLESS).asBoolean();
        ResponseBody responseBody = responseHttp.body();
        boolean bodyExists = responseBody != null;
        InputStream responseBodyStream = null;
        SoftLimitBoundedByteArrayOutputStream outputStreamToRequestAttribute = null;
        TeeInputStream teeInputStream = null;
        try {
            responseBodyStream = bodyExists ? responseBody.byteStream() : null;
            if (responseBodyStream != null && outputBodyToRequestAttribute && outputBodyToResponseContent) {
                outputStreamToRequestAttribute = new SoftLimitBoundedByteArrayOutputStream(maxAttributeSize);
                teeInputStream = new TeeInputStream(responseBodyStream, outputStreamToRequestAttribute);
            }
            if (outputBodyToResponseContent) {
                // clone the flowfile to capture the response
                if (requestFlowFile != null) {
                    responseFlowFile = session.create(requestFlowFile);
                } else {
                    responseFlowFile = session.create();
                }
                // write attributes to response flowfile
                responseFlowFile = session.putAllAttributes(responseFlowFile, statusAttributes);
                // write the response headers as attributes
                // this will overwrite any existing flowfile attributes
                responseFlowFile = session.putAllAttributes(responseFlowFile, convertAttributesFromHeaders(url, responseHttp));
                // can potentially be null in edge cases
                if (bodyExists) {
                    // write content type attribute to response flowfile if it is available
                    if (responseBody.contentType() != null) {
                        responseFlowFile = session.putAttribute(responseFlowFile, CoreAttributes.MIME_TYPE.key(), responseBody.contentType().toString());
                    }
                    if (teeInputStream != null) {
                        responseFlowFile = session.importFrom(teeInputStream, responseFlowFile);
                    } else {
                        responseFlowFile = session.importFrom(responseBodyStream, responseFlowFile);
                    }
                    // emit provenance event
                    final long millis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos);
                    if (requestFlowFile != null) {
                        session.getProvenanceReporter().fetch(responseFlowFile, url.toExternalForm(), millis);
                    } else {
                        session.getProvenanceReporter().receive(responseFlowFile, url.toExternalForm(), millis);
                    }
                }
            }
            // if not successful and request flowfile is not null, store the response body into a flowfile attribute
            if (outputBodyToRequestAttribute && bodyExists) {
                String attributeKey = context.getProperty(PROP_PUT_OUTPUT_IN_ATTRIBUTE).evaluateAttributeExpressions(requestFlowFile).getValue();
                if (attributeKey == null) {
                    attributeKey = RESPONSE_BODY;
                }
                byte[] outputBuffer;
                int size;
                if (outputStreamToRequestAttribute != null) {
                    outputBuffer = outputStreamToRequestAttribute.getBuffer();
                    size = outputStreamToRequestAttribute.size();
                } else {
                    outputBuffer = new byte[maxAttributeSize];
                    size = StreamUtils.fillBuffer(responseBodyStream, outputBuffer, false);
                }
                String bodyString = new String(outputBuffer, 0, size, getCharsetFromMediaType(responseBody.contentType()));
                requestFlowFile = session.putAttribute(requestFlowFile, attributeKey, bodyString);
                final long millis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos);
                session.getProvenanceReporter().modifyAttributes(requestFlowFile, "The " + attributeKey + " has been added. The value of which is the body of a http call to " + url.toExternalForm() + ". It took " + millis + "millis,");
            }
        } finally {
            if (outputStreamToRequestAttribute != null) {
                outputStreamToRequestAttribute.close();
                outputStreamToRequestAttribute = null;
            }
            if (teeInputStream != null) {
                teeInputStream.close();
                teeInputStream = null;
            } else if (responseBodyStream != null) {
                responseBodyStream.close();
                responseBodyStream = null;
            }
        }
        route(requestFlowFile, responseFlowFile, session, context, statusCode);
    } catch (final Exception e) {
        // penalize or yield
        if (requestFlowFile != null) {
            logger.error("Routing to {} due to exception: {}", new Object[] { REL_FAILURE.getName(), e }, e);
            requestFlowFile = session.penalize(requestFlowFile);
            requestFlowFile = session.putAttribute(requestFlowFile, EXCEPTION_CLASS, e.getClass().getName());
            requestFlowFile = session.putAttribute(requestFlowFile, EXCEPTION_MESSAGE, e.getMessage());
            // transfer original to failure
            session.transfer(requestFlowFile, REL_FAILURE);
        } else {
            logger.error("Yielding processor due to exception encountered as a source processor: {}", e);
            context.yield();
        }
        // cleanup response flowfile, if applicable
        try {
            if (responseFlowFile != null) {
                session.remove(responseFlowFile);
            }
        } catch (final Exception e1) {
            logger.error("Could not cleanup response flowfile due to exception: {}", new Object[] { e1 }, e1);
        }
    }
}
Also used : FlowFile(org.apache.nifi.flowfile.FlowFile) OkHttpClient(okhttp3.OkHttpClient) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) TeeInputStream(org.apache.commons.io.input.TeeInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) Request(okhttp3.Request) SoftLimitBoundedByteArrayOutputStream(org.apache.nifi.processors.standard.util.SoftLimitBoundedByteArrayOutputStream) TeeInputStream(org.apache.commons.io.input.TeeInputStream) ComponentLog(org.apache.nifi.logging.ComponentLog) URL(java.net.URL) KeyStoreException(java.security.KeyStoreException) KeyManagementException(java.security.KeyManagementException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ProcessException(org.apache.nifi.processor.exception.ProcessException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) IOException(java.io.IOException) CertificateException(java.security.cert.CertificateException) ResponseBody(okhttp3.ResponseBody) Response(okhttp3.Response) UUID(java.util.UUID) Cache(okhttp3.Cache)

Example 2 with TeeInputStream

use of org.apache.commons.io.input.TeeInputStream in project wso2-axis2-transports by wso2.

the class LogAspect method aroundProcessDocument.

@Around("call(org.apache.axiom.om.OMElement org.apache.axis2.builder.Builder.processDocument(" + "       java.io.InputStream, java.lang.String, org.apache.axis2.context.MessageContext))" + " && args(in, contentType, msgContext)")
public Object aroundProcessDocument(ProceedingJoinPoint proceedingJoinPoint, InputStream in, String contentType, MessageContext msgContext) throws Throwable {
    InputStream tee;
    if (in == null) {
        tee = null;
    } else {
        OutputStream log = LogManager.INSTANCE.createLog("builder");
        // Note: We can't close the log right after the method execution because the
        // message builder may use streaming. LogManager will take care of closing the
        // log for us if anything goes wrong.
        tee = new TeeInputStream(in, log, true);
    }
    return proceedingJoinPoint.proceed(new Object[] { tee, contentType, msgContext });
}
Also used : TeeInputStream(org.apache.commons.io.input.TeeInputStream) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) TeeOutputStream(org.apache.commons.io.output.TeeOutputStream) TeeInputStream(org.apache.commons.io.input.TeeInputStream) Around(org.aspectj.lang.annotation.Around)

Example 3 with TeeInputStream

use of org.apache.commons.io.input.TeeInputStream in project nifi-minifi by apache.

the class FileChangeIngestor method run.

@Override
public void run() {
    logger.debug("Checking for a change");
    if (targetChanged()) {
        logger.debug("Target changed, checking if it's different than current flow.");
        try (FileInputStream configFile = new FileInputStream(configFilePath.toFile());
            ByteArrayOutputStream pipedOutputStream = new ByteArrayOutputStream();
            TeeInputStream teeInputStream = new TeeInputStream(configFile, pipedOutputStream)) {
            if (differentiator.isNew(teeInputStream)) {
                logger.debug("New change, notifying listener");
                // Fill the byteArrayOutputStream with the rest of the request data
                while (teeInputStream.available() != 0) {
                    teeInputStream.read();
                }
                ByteBuffer newConfig = ByteBuffer.wrap(pipedOutputStream.toByteArray());
                ByteBuffer readOnlyNewConfig = newConfig.asReadOnlyBuffer();
                configurationChangeNotifier.notifyListeners(readOnlyNewConfig);
                logger.debug("Listeners notified");
            }
        } catch (Exception e) {
            logger.error("Could not successfully notify listeners.", e);
        }
    }
}
Also used : ByteArrayOutputStream(org.apache.commons.io.output.ByteArrayOutputStream) TeeInputStream(org.apache.commons.io.input.TeeInputStream) ByteBuffer(java.nio.ByteBuffer) FileInputStream(java.io.FileInputStream) IOException(java.io.IOException)

Example 4 with TeeInputStream

use of org.apache.commons.io.input.TeeInputStream in project application by collectionspace.

the class NullResolver method serveSingle.

/**
 * Return a single request from the cspace-ui servlet context
 * @param tenant
 * @param sub
 * @param sc
 * @throws UIException
 * @throws IOException
 */
private void serveSingle(String tenant, CompositeWebUIRequestPart sub, ServletContext sc) throws UIException, IOException {
    // Setup our request object
    UI web = tenantCSPM.get(tenant).getUI("web");
    WebUI webui = (WebUI) web;
    UIMapping[] allmappings = webui.getAllMappings();
    ConfigRoot root = tenantCSPM.get(tenant).getConfigRoot();
    Spec spec = (Spec) root.getRoot(Spec.SPEC_ROOT);
    // this doesn't seem to work yet
    Boolean doMetaConfig = true;
    String[] pathbits = sub.getPrincipalPath();
    String pathinfo = StringUtils.join(pathbits, "/");
    String path = pathinfo;
    Map<String, Object> validmap = doMapping(pathinfo, allmappings, spec);
    if (null != validmap) {
        path = (String) validmap.get("File");
        if (((UIMapping) validmap.get("map")).hasMetaConfig() && doMetaConfig) {
            InputStream is = getFixedContent(sc, path, tenant);
            StringWriter writer = new StringWriter();
            IOUtils.copy(is, writer, "UTF-8");
            String theString = writer.toString();
            /*
				SAXReader reader = new SAXReader();
				reader.setEntityResolver(new NullResolver());
				Document xmlfile = null;

				ByteArrayOutputStream dump = new ByteArrayOutputStream();
				xmlfile = reader.read(new TeeInputStream(is, dump));
			//	log.info(dump.toString("UTF-8"));
			//	log.info(xmlfile.asXML());<tr></tr<.>
			 
			 TODO I want this to work... it just doesn't yet as I haven\'t had time to work on it
			 this is all about replace items in the title etc of the universal files so they become more specific
*/
            for (String metafield : ((UIMapping) validmap.get("map")).getAllMetaConfigs()) {
                String rtext = ((UIMapping) validmap.get("map")).getMetaConfig(metafield).parseValue((Record) validmap.get("record"), (Instance) validmap.get("instance"));
                // try as json
                String regex = "\"" + metafield + "\": \"[^\"]*\"";
                String replacement = "\"" + metafield + "\": \"" + rtext + "\"";
                theString = theString.replaceFirst(regex, replacement);
                // try as xml
                String regex2 = "<" + metafield + ">[^<]*</" + metafield + ">";
                String replacement2 = "<" + metafield + ">" + rtext + "</" + metafield + ">";
                theString = theString.replaceFirst(regex2, replacement2);
            }
            InputStream is2 = new ByteArrayInputStream(theString.getBytes("UTF-8"));
            serveExternalContent(sub, sc, is2, path);
            is.close();
            return;
        }
    }
    if (pathbits[1].equals("bundle")) {
        if (serverCreateMergedExternalContent(sub, sc, pathinfo, tenant)) {
            return;
        }
    }
    if (serverFixedExternalContent(sub, sc)) {
        return;
    }
}
Also used : ConfigRoot(org.collectionspace.chain.csp.config.ConfigRoot) TeeInputStream(org.apache.commons.io.input.TeeInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) UIMapping(org.collectionspace.chain.csp.webui.external.UIMapping) WebUI(org.collectionspace.chain.csp.webui.main.WebUI) WebUI(org.collectionspace.chain.csp.webui.main.WebUI) UI(org.collectionspace.csp.api.ui.UI) StringWriter(java.io.StringWriter) ByteArrayInputStream(java.io.ByteArrayInputStream) JSONObject(org.json.JSONObject) Spec(org.collectionspace.chain.csp.schema.Spec)

Example 5 with TeeInputStream

use of org.apache.commons.io.input.TeeInputStream in project application by collectionspace.

the class NullResolver method serveSingle.

/**
 * abstraction for returning a single item.
 * probably could be simplified with other serveSingle function
 * @param tenant
 * @param servlet_request
 * @param servlet_response
 * @param pathinfo
 * @param pathbits
 * @param sc
 * @throws IOException
 * @throws BadRequestException
 * @throws UnsupportedEncodingException
 */
private void serveSingle(String tenant, HttpServletRequest servlet_request, HttpServletResponse servlet_response, String pathinfo, String[] pathbits, ServletContext sc) throws IOException, BadRequestException, UnsupportedEncodingException {
    // should we redirect this url or just do the normal stuff
    // Setup our request object
    UI web = tenantCSPM.get(tenant).getUI("web");
    WebUI webui = (WebUI) web;
    UIMapping[] allmappings = webui.getAllMappings();
    ConfigRoot root = tenantCSPM.get(tenant).getConfigRoot();
    Spec spec = (Spec) root.getRoot(Spec.SPEC_ROOT);
    // this doesn't seem to work yet
    Boolean doMetaConfig = true;
    String path = pathinfo;
    Map<String, Object> validmap = doMapping(pathinfo, allmappings, spec);
    if (null != validmap) {
        path = (String) validmap.get("File");
        if (((UIMapping) validmap.get("map")).hasMetaConfig() && doMetaConfig) {
            InputStream is = getFixedContent(sc, path, tenant);
            StringWriter writer = new StringWriter();
            IOUtils.copy(is, writer, "UTF-8");
            String theString = writer.toString();
            /*
				SAXReader reader = new SAXReader();
				reader.setEntityResolver(new NullResolver());
				Document xmlfile = null;

				ByteArrayOutputStream dump = new ByteArrayOutputStream();
				xmlfile = reader.read(new TeeInputStream(is, dump));
			//	log.info(dump.toString("UTF-8"));
			//	log.info(xmlfile.asXML());<tr></tr<.>
			 TODO I want this to work... it just doesn't yet as I haven\'t had time to work on it
			 this is all about replace items in the title etc of the universal files so they become more specific
*/
            for (String metafield : ((UIMapping) validmap.get("map")).getAllMetaConfigs()) {
                String rtext = ((UIMapping) validmap.get("map")).getMetaConfig(metafield).parseValue((Record) validmap.get("record"), (Instance) validmap.get("instance"));
                // try as json
                String regex = "\"" + metafield + "\": \"[^\"]*\"";
                String replacement = "\"" + metafield + "\": \"" + rtext + "\"";
                theString = theString.replaceFirst(regex, replacement);
                // try as xml
                String regex2 = "<" + metafield + ">[^<]*</" + metafield + ">";
                String replacement2 = "<" + metafield + ">" + rtext + "</" + metafield + ">";
                theString = theString.replaceFirst(regex2, replacement2);
            }
            InputStream is2 = new ByteArrayInputStream(theString.getBytes("UTF-8"));
            serveContent(servlet_response, is2);
            is.close();
            return;
        }
    }
    if (pathbits[1].equals("bundle")) {
        if (serverCreateMergedExternalContent(servlet_request, servlet_response, sc, pathinfo, tenant)) {
            return;
        }
    }
    if (serverFixedExternalContent(servlet_request, servlet_response, sc, path, tenant)) {
        return;
    }
}
Also used : ConfigRoot(org.collectionspace.chain.csp.config.ConfigRoot) TeeInputStream(org.apache.commons.io.input.TeeInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) UIMapping(org.collectionspace.chain.csp.webui.external.UIMapping) WebUI(org.collectionspace.chain.csp.webui.main.WebUI) WebUI(org.collectionspace.chain.csp.webui.main.WebUI) UI(org.collectionspace.csp.api.ui.UI) StringWriter(java.io.StringWriter) ByteArrayInputStream(java.io.ByteArrayInputStream) JSONObject(org.json.JSONObject) Spec(org.collectionspace.chain.csp.schema.Spec)

Aggregations

TeeInputStream (org.apache.commons.io.input.TeeInputStream)14 InputStream (java.io.InputStream)10 ByteArrayOutputStream (java.io.ByteArrayOutputStream)5 FileInputStream (java.io.FileInputStream)4 IOException (java.io.IOException)4 ByteArrayInputStream (java.io.ByteArrayInputStream)3 File (java.io.File)3 FileOutputStream (java.io.FileOutputStream)3 StringWriter (java.io.StringWriter)2 URI (java.net.URI)2 Header (org.apache.commons.httpclient.Header)2 TeeOutputStream (org.apache.commons.io.output.TeeOutputStream)2 ConfigRoot (org.collectionspace.chain.csp.config.ConfigRoot)2 Spec (org.collectionspace.chain.csp.schema.Spec)2 UIMapping (org.collectionspace.chain.csp.webui.external.UIMapping)2 WebUI (org.collectionspace.chain.csp.webui.main.WebUI)2 UI (org.collectionspace.csp.api.ui.UI)2 JSONObject (org.json.JSONObject)2 FilterOutputStream (java.io.FilterOutputStream)1 OutputStream (java.io.OutputStream)1