问:
javax.net.ssl.SSLHandshakeException: handshake_failure when using JMeter with SSL (JDK8)
I am writing a JMeter test plan to connect to SSL port (Tomcat Connector). I receive a SSLHandshakeException (handshake_failure) when connecting to SSL port using any of the three JMeter SSL client implementations (HttpClient4, HttpClient3.1, Java) on JDK8 (1.8.0_51). If I use JDK7 (1.7.0_75) - everything works as expected.

```<code>Client JDK: HotSpot 1.8.0_51
Client OS: Mac OSX 10.10.2
JMeter version: 2.13

Server: Tomcat 7.0.63 (latest)
Server SSL CipherSuite: RC4-SHA
Server SSL Protocol: all
Server Java: OpenJDK 1.7.0_79
</code>```

Here are some things I have already tried:

(1) I tried replacing the JCE Unlimited Strength JARs, as suggested on a similar question:
SSLHandshakeException while connecting to a https site

No changes in error messages or logfile, JDK8 client would not connect to the SSL server.

(2) I turned on debugging as described here: https://blogs.oracle.com/java-platform-group/entry/diagnosing_tls_ssl_and_https. Starting JMeter with JVM_ARGS set to -Djavax.net.debug=ssl:handshake:verbose. The logfile (attached below) did not hint any reasons what the issue might be.

(3) I tried specifying the HTTPS procotol, e.g. -Dhttps.protocols=SSLv3. No luck. SSLv3 was disabled or cipher were not matching:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

(4) I tried disabling SNI, e.g. -Djsse.enableSNIExtension=false. No luck either.

So, I am forced to use the JDK7 for now, until I can get my JMeter to run with JDK8, and I'd like to fix that.

So, the issue is in how JDK8 handles SSL clients differently from JDK7. Also, the server (Tomcat Connector) would need to support appropriate ciphers and protocols, but that's out of my control for now.

Here are relevant logs:

```<code>X509KeyManager passed to SSLContext.init():  need an X509ExtendedKeyManager for SSLEngine use
trigger seeding of SecureRandom
done seeding SecureRandom
Agents (clients) 1-2, setSoTimeout(0) called
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  *** ClientHello, TLSv1.2
GMT: 1422637724 bytes = { RandomCookie:  GMT: 1422637724 bytes = { 71, 27, 101, 246, 26, 99, 64, 213, 53, 66, 156, 66, 118, 137, 247113, , 226, 86, 121, 189, 207, 175, 98, 46, 64, 242, 48, 19, 30, 66, 251, 120, 125, 249, 63, 114, 254, 246, 5, 168, 17, 190, 214, 228, 90, 165128 }
Session ID:  , 113, {}
157, 211, 230, 144, Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
145, 63, Compression Methods:  { 238, 0178 }
Session ID:  {}
 }
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
***
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
***
Agents (clients) 1-2, WRITE: TLSv1.2 Handshake, length = 237
Agents (clients) 1-1, WRITE: TLSv1.2 Handshake, length = 237
Agents (clients) 1-2, READ: TLSv1.2 Alert, length = 2
Agents (clients) 1-2, RECV TLSv1.2 ALERT:  fatal, handshake_failure
Agents (clients) 1-2, called closeSocket()
Agents (clients) 1-2, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Agents (clients) 1-2, called close()
Agents (clients) 1-2, called closeInternal(true)
Agents (clients) 1-1, READ: TLSv1.2 Alert, length = 2
Agents (clients) 1-1, RECV TLSv1.2 ALERT:  fatal, handshake_failure
Agents (clients) 1-1, called closeSocket()
Agents (clients) 1-1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Agents (clients) 1-1, called close()
Agents (clients) 1-1, called closeInternal(true)
</code>```

Here's the stacktrace I get in JMeter logfile:

```<code>javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
    at org.apache.jmeter.protocol.http.sampler.HTTPJavaImpl.sample(HTTPJavaImpl.java:483)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1146)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1135)
    at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:434)
    at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:261)
    at java.lang.Thread.run(Thread.java:745)
</code>```

So, how do I make JDK8 client in JMeter talk to SSL port using protocols and ciphers allowed by the server.

Thanks!

Edit: Added SSL Labs test results

```<code>Protocols
    TLS 1.2    Yes
    TLS 1.1    Yes
    TLS 1.0    Yes
    SSL 3      No
    SSL 2      No

Cipher Suites (sorted by strength as the server has no preference; deprecated and SSL 2 suites at the end)
    TLS_RSA_WITH_RC4_128_SHA (0x5)      WEAK        128

Clients
    Java 6u45    No SNI 2    TLS 1.0    TLS_RSA_WITH_RC4_128_SHA (0x5) No FS    RC4    128
    Java 7u25                TLS 1.0    TLS_RSA_WITH_RC4_128_SHA (0x5) No FS    RC4    128
    Java 8u31                TLS 1.2    TLS_RSA_WITH_RC4_128_SHA (0x5) No FS    RC4    128
</code>```

答:
There is a solution that allows JMeter to connect to insecure endpoints (or those that use old or not secured enough protocols):

Find your JRE;

Open jre\lib\security\ folder;

Make a backup copy of java.security file;

Edit java.security file and comment out all lines that disable insecure algorithms - search for 'disabledAlgorithms' string (don't forget to comment out both lines in multiline settings), they look like:

jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
    DSA keySize < 1024, EC keySize < 224

save the file and restart JMeter.

Java connections are now allowed to use old protocols, so JMeter can properly work.

REMEMBER it's security!

These settings are global, and will affect all programs that use the same JRE. If you found this fix works and useful for your system, DO create a copy of your JRE, and set a path to it in jmeter.bat. Return your global settings from backed up copy of java.security file.

Body:
I am writing a JMeter test plan to connect to SSL port (Tomcat Connector). I receive a SSLHandshakeException (handshake_failure) when connecting to SSL port using any of the three JMeter SSL client implementations (HttpClient4, HttpClient3.1, Java) on JDK8 (1.8.0_51). If I use JDK7 (1.7.0_75) - everything works as expected.

Client JDK: HotSpot 1.8.0_51
Client OS: Mac OSX 10.10.2
JMeter version: 2.13

Server: Tomcat 7.0.63 (latest)
Server SSL CipherSuite: RC4-SHA
Server SSL Protocol: all
Server Java: OpenJDK 1.7.0_79

Here are some things I have already tried:

(1) I tried replacing the JCE Unlimited Strength JARs, as suggested on a similar question:
SSLHandshakeException while connecting to a https site

No changes in error messages or logfile, JDK8 client would not connect to the SSL server.

(2) I turned on debugging as described here: https://blogs.oracle.com/java-platform-group/entry/diagnosing_tls_ssl_and_https. Starting JMeter with JVM_ARGS set to -Djavax.net.debug=ssl:handshake:verbose. The logfile (attached below) did not hint any reasons what the issue might be.

(3) I tried specifying the HTTPS procotol, e.g. -Dhttps.protocols=SSLv3. No luck. SSLv3 was disabled or cipher were not matching:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

(4) I tried disabling SNI, e.g. -Djsse.enableSNIExtension=false. No luck either.

So, I am forced to use the JDK7 for now, until I can get my JMeter to run with JDK8, and I'd like to fix that.

So, the issue is in how JDK8 handles SSL clients differently from JDK7. Also, the server (Tomcat Connector) would need to support appropriate ciphers and protocols, but that's out of my control for now.

Here are relevant logs:

X509KeyManager passed to SSLContext.init():  need an X509ExtendedKeyManager for SSLEngine use
trigger seeding of SecureRandom
done seeding SecureRandom
Agents (clients) 1-2, setSoTimeout(0) called
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  *** ClientHello, TLSv1.2
GMT: 1422637724 bytes = { RandomCookie:  GMT: 1422637724 bytes = { 71, 27, 101, 246, 26, 99, 64, 213, 53, 66, 156, 66, 118, 137, 247113, , 226, 86, 121, 189, 207, 175, 98, 46, 64, 242, 48, 19, 30, 66, 251, 120, 125, 249, 63, 114, 254, 246, 5, 168, 17, 190, 214, 228, 90, 165128 }
Session ID:  , 113, {}
157, 211, 230, 144, Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
145, 63, Compression Methods:  { 238, 0178 }
Session ID:  {}
 }
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
***
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
***
Agents (clients) 1-2, WRITE: TLSv1.2 Handshake, length = 237
Agents (clients) 1-1, WRITE: TLSv1.2 Handshake, length = 237
Agents (clients) 1-2, READ: TLSv1.2 Alert, length = 2
Agents (clients) 1-2, RECV TLSv1.2 ALERT:  fatal, handshake_failure
Agents (clients) 1-2, called closeSocket()
Agents (clients) 1-2, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Agents (clients) 1-2, called close()
Agents (clients) 1-2, called closeInternal(true)
Agents (clients) 1-1, READ: TLSv1.2 Alert, length = 2
Agents (clients) 1-1, RECV TLSv1.2 ALERT:  fatal, handshake_failure
Agents (clients) 1-1, called closeSocket()
Agents (clients) 1-1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Agents (clients) 1-1, called close()
Agents (clients) 1-1, called closeInternal(true)

Here's the stacktrace I get in JMeter logfile:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
    at org.apache.jmeter.protocol.http.sampler.HTTPJavaImpl.sample(HTTPJavaImpl.java:483)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1146)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1135)
    at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:434)
    at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:261)
    at java.lang.Thread.run(Thread.java:745)

So, how do I make JDK8 client in JMeter talk to SSL port using protocols and ciphers allowed by the server.

Thanks!

Edit: Added SSL Labs test results

Protocols
    TLS 1.2    Yes
    TLS 1.1    Yes
    TLS 1.0    Yes
    SSL 3      No
    SSL 2      No

Cipher Suites (sorted by strength as the server has no preference; deprecated and SSL 2 suites at the end)
    TLS_RSA_WITH_RC4_128_SHA (0x5)      WEAK        128

Clients
    Java 6u45    No SNI 2    TLS 1.0    TLS_RSA_WITH_RC4_128_SHA (0x5) No FS    RC4    128
    Java 7u25                TLS 1.0    TLS_RSA_WITH_RC4_128_SHA (0x5) No FS    RC4    128
    Java 8u31                TLS 1.2    TLS_RSA_WITH_RC4_128_SHA (0x5) No FS    RC4    128


来源: stackexchange

问:
No email data returned with wl.signin,wl.emails scopes
I am using the https://github.com/jaredhanson/passport-windowslive NPM package to implement Microsoft account authentication for my NodeJS app. Recently (since 22 April), I have been seeing a few cases in my server logs that show a user trying to login, but the data in the OAuth callback to our server contains an empty array for the emails. This is despite me explicitly specifying the wl.signin,wl.emails scopes. These cases are rare (happens once or twice a day), but frequent enough to make my service monitoring alerts annoying.

This is the user object returned: Note that apart from the user ID, which i hid away for privacy reasons, all the other fields are indeed null or empty as attached in the callback.

{"id":"<id hidden>","displayName":null,"name":{"familyName":null,"givenName":null},"emails":[],"photos":[{"value":"https://apis.live.net/v5.0/<id hidden>/picture"}],"provider":"windowslive","_raw":"{\r   \"id\": \"<id hidden>\", \r   \"name\": null, \r   \"first_name\": null, \r   \"last_name\": null, \r   \"gender\": null, \r   \"emails\": {\r      \"preferred\": null, \r      \"account\": null, \r      \"personal\": null, \r      \"business\": null\r   }, \r   \"locale\": null\r}","_json":{"id":"<id hidden>","name":null,"first_name":null,"last_name":null,"gender":null,"emails":{"preferred":null,"account":null,"personal":null,"business":null},"locale":null}}

Did something change in the Windows Live API server recently? Is there a bug somewhere?

答:
I had this issue. Turns out it was a problem with the user account.

I went into my account (OneDrive) and changed my personal email address in the select list (from 'not selected' to my account email address) in the profile. After that the API started returning the correct details.

Seems like an internal bug - should default to the account email if not otherwise set.

ContentLicense: CC BY-SA 3.0


问:
Laravel 5.4: fetching data from url with no parameter
I have noticed a strange behaviour while pulling data in my view from the controller:

Lets say i have this route defined in my routes(web.php):

```<code>Route::get('user/getPageContent/{id}', ['uses'=>'Users\DashboardController@getPageContent', 'as'=>'user.pagecontent']);
</code>```

Now in my DashboardController, i have the function that returns the json:

```<code>public function getPageContent($id)
{
    $content_model = new Content();
    $content = $content_model->getContent($id);
    $response = response()->json($content);

    return $response;
}
</code>```

and to pull this in my view, i use Jquery $.get method:

```<code>$.get('user/getPageContent/'+id, function(response){
    //logic goes here
});
</code>```

this works well. now if i create the same functionality for a url with no parameter, i do not get a response: i create the route as a get request:

```<code>Route::get('user/getAssessmentPage', ['uses'=>'Users\DashboardController@getAssessmentPage', 'as'=>'user.assessmentpage']);
</code>```

define the function in the controller:

```<code>public function getAssessmentPage()
{
    $content= Assessment_Page::all();
    $response = response()->json($content);

    return $response;
}
</code>```

and try to access it in my view:

```<code>$.get('user/getAssessmentPage', function(response){
    console.log(response);
});
</code>```

but i do not get a response. no response, no error in the console, nothing. so my question is, for url's with no parameters as shown, what would be the way to go to pulling the data?

should also mention i've even given the .load method a try but still no response.

答:
So the issue was in my routes. this is how they were originally structured:

```<code>Route::resource('user', 'Users\DashboardController');
Route::group(['middleware' => ['auth']], function () {
    Route::get('user', ['uses'=>'Users\DashboardController@index', 'as'=>'user.layout']);
    Route::get('user/displayMenuItems', ['uses'=>'Users\DashboardController@displayMenuItems', 'as'=>'user.menuitems']);
    Route::get('user/getSubChapterContent/{id}', ['uses'=>'Users\DashboardController@getSubChapterContent', 'as'=>'user.subchaptercontent']);
    Route::get('user/getPageContent/{id}', ['uses'=>'Users\DashboardController@getPageContent', 'as'=>'user.pagecontent']);
    Route::get('user/getQuiz/{chapter_id}', ['uses'=>'Users\DashboardController@getQuiz', 'as'=>'user.quiz']);
    Route::get('user/getCorrectChoice/{question_id}',['uses'=>'Users\DashboardController@getCorrectChoice', 'as'=>'user.getanswer'] );
    Route::post('user/logChapterQuizes', ['uses'=>'Users\DashboardController@logChapterQuizes', 'as'=>'user.logquiz']);
    Route::get('user/getAssessmentPage', ['uses'=>'Users\DashboardController@getAssessmentPage', 'as'=>'user.getAssessmentPage']);
});
</code>```

but after moving the Route::resource('user', 'Users\DashboardController') below the Route::group, i can now get the response.

The order of routes matters.

was fortunate enough to get the answer from laracasts. see this thread:

https://laracasts.com/discuss/channels/laravel/laravel-54-fetching-data-from-url-with-no-parameter

Body:
I have noticed a strange behaviour while pulling data in my view from the controller:

Lets say i have this route defined in my routes(web.php):

Route::get('user/getPageContent/{id}', ['uses'=>'Users\DashboardController@getPageContent', 'as'=>'user.pagecontent']);

Now in my DashboardController, i have the function that returns the json:

public function getPageContent($id)
{
    $content_model = new Content();
    $content = $content_model->getContent($id);
    $response = response()->json($content);

    return $response;
}

and to pull this in my view, i use Jquery $.get method:

$.get('user/getPageContent/'+id, function(response){
    //logic goes here
});

this works well. now if i create the same functionality for a url with no parameter, i do not get a response: i create the route as a get request:

Route::get('user/getAssessmentPage', ['uses'=>'Users\DashboardController@getAssessmentPage', 'as'=>'user.assessmentpage']);

define the function in the controller:

public function getAssessmentPage()
{
    $content= Assessment_Page::all();
    $response = response()->json($content);

    return $response;
}

and try to access it in my view:

$.get('user/getAssessmentPage', function(response){
    console.log(response);
});

but i do not get a response. no response, no error in the console, nothing. so my question is, for url's with no parameters as shown, what would be the way to go to pulling the data?

should also mention i've even given the .load method a try but still no response.

Body:
So the issue was in my routes. this is how they were originally structured:

Route::resource('user', 'Users\DashboardController');
Route::group(['middleware' => ['auth']], function () {
    Route::get('user', ['uses'=>'Users\DashboardController@index', 'as'=>'user.layout']);
    Route::get('user/displayMenuItems', ['uses'=>'Users\DashboardController@displayMenuItems', 'as'=>'user.menuitems']);
    Route::get('user/getSubChapterContent/{id}', ['uses'=>'Users\DashboardController@getSubChapterContent', 'as'=>'user.subchaptercontent']);
    Route::get('user/getPageContent/{id}', ['uses'=>'Users\DashboardController@getPageContent', 'as'=>'user.pagecontent']);
    Route::get('user/getQuiz/{chapter_id}', ['uses'=>'Users\DashboardController@getQuiz', 'as'=>'user.quiz']);
    Route::get('user/getCorrectChoice/{question_id}',['uses'=>'Users\DashboardController@getCorrectChoice', 'as'=>'user.getanswer'] );
    Route::post('user/logChapterQuizes', ['uses'=>'Users\DashboardController@logChapterQuizes', 'as'=>'user.logquiz']);
    Route::get('user/getAssessmentPage', ['uses'=>'Users\DashboardController@getAssessmentPage', 'as'=>'user.getAssessmentPage']);
});

but after moving the Route::resource('user', 'Users\DashboardController') below the Route::group, i can now get the response.

The order of routes matters.

was fortunate enough to get the answer from laracasts. see this thread:

https://laracasts.com/discuss/channels/laravel/laravel-54-fetching-data-from-url-with-no-parameter


问:
Python web scraping exchange prices
I want scraping the exchange prices informations from this website and after take it into a database: https://www.mnb.hu/arfolyamok

I wrote this code, but something wrong with it. How can i fix it, where i have to change it?
I am working with Python 2.7.13 on Windows 7.

The code is here:

import csv
import requests
from BeautifulSoup import BeautifulSoup

url = 'https://www.mnb.hu/arfolyamok'
response = requests.get(url)
html = response.content

soup = BeautifulSoup(html)
table = soup.find('tbody', attrs={'class': 'stripe'})

list_of_rows = []
for row in table.findAll('tr')[1:]:
    list_of_cells = []
   for cell in row.findAll('td'):
       text = cell.text.replace(' ', '')
        list_of_cells.append(text)
   list_of_rows.append(list_of_cells)

print list_of_rows

outfile = open("./inmates.csv", "wb")
writer = csv.writer(outfile)
writer.writerow(["Pénznem", "Devizanév", "Egység", "Forintban kifejezett érték"])
writer.writerows(list_of_rows)```

答: Add # coding=utf-8 to the top of your code. This will help solve the SyntaxError you are receiving. Also make sure your indentation is correct!

Title: Python web scraping exchange prices


问:
scope.$on is not working when created inside a directive
I have created a directive for my application which is mentioned in the following question
How do you serve a file for download with AngularJS or Javascript? Directive code is as like below

```<code>    appModule.directive('fileDownload', function ($compile) {
        var fd = {
            restrict: 'A',
            link: function (scope, iElement, iAttrs) {

                scope.$on("downloadFile", function (e, url) {
                    var iFrame = iElement.find("iframe");
                    if (!(iFrame && iFrame.length > 0)) {
                        iFrame = $("<iframe style='position:fixed;display:none;top:-1px;left:-1px;'/>");
                        iElement.append(iFrame);
                    }
                    iFrame.attr("src", url);
                });
            }
        };
        return fd;
    });
</code>```

Here scope.$on is used, when I call this event via $scope.$emit or $scope.$broadcast, it is not working. My controller code is like below

```<code>    function reportsController($scope, $http) {
        var self = this;

        $scope.$broadcast("downloadFile", 'http://google.com');
        $scope.$emit("downloadFile", 'http://google.com');
    }
</code>```

and my html file is as below

```<code>    <div ng-controller="reportsController" id="repctrl">
        <a file-download></a>
    </div>
</code>```

What I am doing wrong here?

@Edit: Added the subscribe ($on) in the compile phase so as to avoid the usage of $timeout in controller. Here you can look the example

答:
something similar happen to me when i try to call a function in the directive of a modal,

what i had to do was to make a delay after I made the call to show the modal:

```<code>        $timeout(function () {
            $rootScope.$broadcast('obtiene-plantillas');
        }, 500);
</code>```

Body:
I have created a directive for my application which is mentioned in the following question
How do you serve a file for download with AngularJS or Javascript? Directive code is as like below

    appModule.directive('fileDownload', function ($compile) {
        var fd = {
            restrict: 'A',
            link: function (scope, iElement, iAttrs) {

                scope.$on("downloadFile", function (e, url) {
                    var iFrame = iElement.find("iframe");
                    if (!(iFrame && iFrame.length > 0)) {
                        iFrame = $("");
                        iElement.append(iFrame);
                    }
                    iFrame.attr("src", url);
                });
            }
        };
        return fd;
    });

Here scope.$on is used, when I call this event via $scope.$emit or $scope.$broadcast, it is not working. My controller code is like below

    function reportsController($scope, $http) {
        var self = this;

        $scope.$broadcast("downloadFile", 'http://google.com');
        $scope.$emit("downloadFile", 'http://google.com');
    }

and my html file is as below

What I am doing wrong here?

@Edit: Added the subscribe ($on) in the compile phase so as to avoid the usage of $timeout in controller. Here you can look the example

Body:
something similar happen to me when i try to call a function in the directive of a modal,

what i had to do was to make a delay after I made the call to show the modal:

        $timeout(function () {
            $rootScope.$broadcast('obtiene-plantillas');
        }, 500);


问:
Rails - where to put model helper methods
I want to hide certain implementations from the main Model methods, because of clean code reasons. I don't want my Model to contain a lot of huge methods, only the clearest and verbose functionalities.

For example:

```<code>class SomeModel
  #included stuff
  #fields & attrs

  def modelMethod
      variable = functionality1(functionality2)
      if some condition
        functionality3
      else
        functionality4
      end
  end
</code>```

Should I put my functionality methods under a private or protected part at the end of the same model file, or should I put them into a helper file?

If I'm right, the codes in the helpers are only used for the View. What is the convention for this?

答:
If you have a method or set of methods that are used in various models:
  Rails Concerns

This is different from private/protected and you can have private/protected methods in a concern.  This is just how to extract out duplication.

If you have a method that is needed by the model, and only the model (not subclasses of the model, and never called outside the class:
  private

If you have a method that is needed by the model and its subclasses but not from outside the model:
  protected

If you need to be able to call the method from outside the class:
  neither

this answer goes into better detail on those

Body:
I want to hide certain implementations from the main Model methods, because of clean code reasons. I don't want my Model to contain a lot of huge methods, only the clearest and verbose functionalities.

For example:

class SomeModel
  #included stuff
  #fields & attrs

  def modelMethod
      variable = functionality1(functionality2)
      if some condition
        functionality3
      else
        functionality4
      end
  end

Should I put my functionality methods under a private or protected part at the end of the same model file, or should I put them into a helper file?

If I'm right, the codes in the helpers are only used for the View. What is the convention for this?


问:
Elixir Ecto get all records between two unix epochs
I am trying to to what I thought was a pretty basic ecto query to get the records from between two unix timestamps. Something along the lines of:

```<code>b = Ecto.DateTime.from_unix!(begin_utc_epoch, :second)  |> DateTime.to_naive
e = Ecto.DateTime.from_unix!(end_utc_epoch, :second)  |> DateTime.to_naive
query = from r in MyModel,
where r.inserted_at > ^b and r.inserted_at < ^e
</code>```

I am getting nothing but errors. At the moment it is:

(FunctionClauseError) no function clause matching in DateTime.to_naive/1

I read somewhere that I should be using NaiveDateTime so have been trying to convert to naive time stamps. Any help would be appreciated. I am sure I am doing something wrong because it seems too complicated.  Obviously, I am very new to Elixir.  Thanks in advance.

答:
If your inserted_at data type is a NaiveDateTime, then you can just work with DateTime for the conversion:

```<code>b = DateTime.from_unix!(begin_utc_epoch)  |> DateTime.to_naive
e = DateTime.from_unix!(end_utc_epoch)  |> DateTime.to_naive

query =
  from r in MyModel,
  where: r.inserted_at > ^b and r.inserted_at < ^e
</code>```

Body:
I am trying to to what I thought was a pretty basic ecto query to get the records from between two unix timestamps. Something along the lines of:

b = Ecto.DateTime.from_unix!(begin_utc_epoch, :second)  |> DateTime.to_naive
e = Ecto.DateTime.from_unix!(end_utc_epoch, :second)  |> DateTime.to_naive
query = from r in MyModel,
where r.inserted_at > ^b and r.inserted_at < ^e

I am getting nothing but errors. At the moment it is:

(FunctionClauseError) no function clause matching in DateTime.to_naive/1

I read somewhere that I should be using NaiveDateTime so have been trying to convert to naive time stamps. Any help would be appreciated. I am sure I am doing something wrong because it seems too complicated.  Obviously, I am very new to Elixir.  Thanks in advance.

Body:
If your inserted_at data type is a NaiveDateTime, then you can just work with DateTime for the conversion:

b = DateTime.from_unix!(begin_utc_epoch)  |> DateTime.to_naive
e = DateTime.from_unix!(end_utc_epoch)  |> DateTime.to_naive

query =
  from r in MyModel,
  where: r.inserted_at > ^b and r.inserted_at < ^e


问:
Spring Cloud Stream Reactor Kafka Integration
Why do not we have direct integration for Reactive Kafka in Spring Cloud Stream? </p>

答: You can track this on Spring Kafka project on initial POC and I believe Spring Cloud Stream would make use of this once the final integration is done.</p>


问:
MF SinkWriter Write Sample Failed
I'm trying to encode the ID3D11Texture2D to mp4 using MediaFoundation. Below is my current code.

Initializing Sink Writer

```<code>private int InitializeSinkWriter(String outputFile, int videoWidth, int videoHeight)
    {
        IMFMediaType mediaTypeIn = null;
        IMFMediaType mediaTypeOut = null;
        IMFAttributes attributes = null;

        int hr = 0;

        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateAttributes(out attributes, 1);
        if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 1);
        if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_LOW_LATENCY, 1);

        // Create the sink writer
        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateSinkWriterFromURL(outputFile, null, attributes, out sinkWriter);

        // Create the output type
        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateMediaType(out mediaTypeOut);
        if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video);
        if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_TRANSCODE_CONTAINERTYPE, MFTranscodeContainerType.MPEG4);
        if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.H264);
        if (Succeeded(hr)) hr = (int)mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AVG_BITRATE, videoBitRate);
        if (Succeeded(hr)) hr = (int)mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)MFVideoInterlaceMode.Progressive);

        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeSize(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight);
        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1);
        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
        if (Succeeded(hr)) hr = (int)sinkWriter.AddStream(mediaTypeOut, out streamIndex);

        // Create the input type
        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateMediaType(out mediaTypeIn);
        if (Succeeded(hr)) hr = (int)mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video);
        if (Succeeded(hr)) hr = (int)mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.ARGB32);
        if (Succeeded(hr)) hr = (int)mediaTypeIn.SetUINT32(MFAttributesClsid.MF_SA_D3D11_AWARE, 1);
        if (Succeeded(hr)) hr = (int)mediaTypeIn.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)MFVideoInterlaceMode.Progressive);
        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeSize(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight);
        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1);
        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
        if (Succeeded(hr)) hr = (int)sinkWriter.SetInputMediaType(streamIndex, mediaTypeIn, null);

        // Start accepting data
        if (Succeeded(hr)) hr = (int)sinkWriter.BeginWriting();

        COMBase.SafeRelease(mediaTypeOut);
        COMBase.SafeRelease(mediaTypeIn);

        return hr;
    }
</code>```

Writing frame

```<code> int hr = 0;
        IMFSample sample = null;
        IMFMediaBuffer buffer = null;
        IMF2DBuffer p2Dbuffer = null;
        object texNativeObject = Marshal.GetObjectForIUnknown(surface.NativePointer);

        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateDXGISurfaceBuffer(new Guid("6f15aaf2-d208-4e89-9ab4-489535d34f9c"), texNativeObject, 0, false, out p2Dbuffer);

        buffer = MFVideoEncoderST.ReinterpretCast<IMF2DBuffer,IMFMediaBuffer>(p2Dbuffer);
        int length=0;
        if (Succeeded(hr)) hr = (int)p2Dbuffer.GetContiguousLength(out length);
        if (Succeeded(hr)) hr = (int)buffer.SetCurrentLength(length);

        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateVideoSampleFromSurface(null, out sample);

        if (Succeeded(hr)) hr = (int)sample.AddBuffer(buffer);
        if (Succeeded(hr)) hr = (int)sample.SetSampleTime(prevRecordingDuration);
        if (Succeeded(hr)) hr = (int)sample.SetSampleDuration((recordDuration - prevRecordingDuration));

        if (Succeeded(hr)) hr = (int)sinkWriter.WriteSample(streamIndex, sample);

        COMBase.SafeRelease(sample);
        COMBase.SafeRelease(buffer);
</code>```

using MFTRACE I'm getting the below error.

```<code>    02:48:04.99463 CMFSinkWriterDetours::WriteSample @024BEA18 Stream Index 0x0, Sample @17CEACE0, Time 571ms, Duration 16ms, Buffers 1, Size 4196352B,2088,2008 02:48:04.99465 CMFSinkWriterDetours::WriteSample @024BEA18 failed hr=0x887A0005 (null)2088,2008
02:48:05.01090 CMFSinkWriterDetours::WriteSample @024BEA18 Stream Index 0x0, Sample @17CE9FC0, Time 587ms, Duration 17ms, Buffers 1, Size 4196352B,2088,2008 02:48:05.01091 CMFSinkWriterDetours::WriteSample @024BEA18 failed hr=0x887A0005 (null)2088,2008
02:48:05.02712 CMFSinkWriterDetours::WriteSample @024BEA18 Stream Index 0x0, Sample @17CEACE0, Time 604ms, Duration 16ms, Buffers 1, Size 4196352B,2088,2008 02:48:05.02713 CMFSinkWriterDetours::WriteSample @024BEA18 failed hr=0x887A0005 (null)
</code>```

Can anyone tell me whats wrong with my code? I can only produce 0 bytes of mp4 file.

答:
There are a few potential problems that occur to me here. Roman mentioned the two big ones so I'll elaborate on those. I have a couple other critiques / suggestions for you as well.

Not using IMFDXGIDeviceManager

In order to use hardware acceleration within Media Foundation, you need to create a DirectX device manager object, either an IDirect3DDeviceManager9 for DX9 or in your case an IMFDXGIDeviceManager for DXGI. I strongly suggest reading all the MSDN documentation of that interface. The reason this is necessary is because the same DX device must be shared across all the cooperating hardware MF transforms being used, since they all need access to the shared GPU memory the device controls, and each one needs exclusive control of the device while it's working, so a locking system is needed. The device manager object provides that locking system, and is also the standard way of providing a DX device to one or more transforms. For DXGI, you create this using MFCreateDXGIDeviceManager.

From there, you need to create your DX11 device, and call IMFDXGIDeviceManager::ResetDevice with your DX11 device. You then need to set the device manager for the Sink Writer itself, which is not done in the code you provided above. That is accomplished like this:

// ... inside your InitializeSinkWriter function that you listed above

// I'm assuming you've already created and set up the DXGI device manager elsewhere
IMFDXGIDeviceManager pDeviceManager;

// Passing 3 as the argument because we're adding 3 attributes immediately, saves re-allocations
if (Succeeded(hr)) hr = (int)MFExtern.MFCreateAttributes(out attributes, 3);
if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 1);
if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_LOW_LATENCY, 1);

// Here's the key piece!
if (Succeeded(hr)) hr = (int)attributes.SetUnknown(MFAttributesClsid.MF_SINK_WRITER_D3D_MANAGER, pDeviceManager);

// Create the sink writer
if (Succeeded(hr)) hr = (int)MFExtern.MFCreateSinkWriterFromURL(outputFile, null, attributes, out sinkWriter);
```

<p>This will actually enable D3D11 support for the hardware encoder and allow it access to read the <code>Texture2D</code> you're passing in. It's worth noting that <code>MF_SINK_WRITER_D3D_MANAGER</code> works for both DX9 and DXGI device managers.
<hr/></p>

<h2>Encoder buffering multiple <code>IMFSample</code> instances of the same texture</h2>

<p>This is a potential cause of your problem as well - at the very least it will lead to a lot of unintended behavior even if it isn't the cause of the obvious problem. Building off Roman's comment, many encoders will buffer multiple frames as part of their encoding process. You don't see that behavior when using the Sink Writer because it handles all the detail work for you. However, what you are trying to accomplish (i.e. sending D3D11 textures as input frames) is sufficiently low level that you start having to worry about the internal details of the encoder MFT being used by the Sink Writer.</p>

<p>Most video encoder MFTs will use an internal buffer of some size to store the last <em>N</em> samples provided via <code>IMFTransform::ProcessInput</code>. This has the side effect that multiple samples must be provided as inputs before any output will be generated. Video encoders need access to multiple samples in order because they use the subsequent frames to determine how to encode the current frame. In other words, if the decoder is working on frame 0, it might need to see frames 1, 2, and 3 as well. From a technical standpoint, this is because of things like inter-frame prediction and motion estimation. Once the encoder is finished processing the oldest sample, it generates an output buffer (another <code>IMFSample</code> object, but this time on the output side via <code>IMFTransform::ProcessOutput</code>) then discards the input sample it was working on (by calling <code>IUnknown::Release</code>), then requests more input, and eventually moves on to the next frame. You can read more about this process in the MSDN article Processing Data in the Encoder</p>

<p>What this means, as Roman alluded to, is that you are encapsulating an <code>ID3D11Texture2D</code> inside an <code>IMFMediaBuffer</code> inside an <code>IMFSample</code> and then passing that to the Sink Writer. That sample is likely being buffered by the encoder as part of the encoding process. As the encoder is working, the contents of that <code>Texture2D</code> are probably changing, which can cause a variety of problems. Even if that didn't cause program errors, it would certainly lead to very strange encoded video outputs. Imagine if the encoder is trying to predict how the visual content of one frame changes in the next frame, and then the actual visual content of both frames is updated out from under the encoder!</p>

<p>This specific problem is happening because the encoder only has a pointer reference to your <code>IMFSample</code> instance, which is ultimately just a pointer itself to your <code>ID3D11Texture2D</code> object, and that object is a kind of pointer reference to mutable graphics memory. Ultimately, the contents of that graphics memory are changing due to some other part of your program, but because it's always the same GPU texture being updated, every single sample you send the encoder points to the same single texture. That means whenever you update the texture, by changing GPU memory, all the active <code>IMFSample</code> objects will reflect those changes, since they are all effectively pointing to the same GPU texture.</p>

<p>To fix this, you'll need to allocate multiple <code>ID3D11Texture2D</code> objects, such that you can pair up one texture with one <code>IMFSample</code> when providing it to the Sink Writer. This will fix the problem of all the samples pointing to the same single GPU texture by making each sample point to a unique texture. You won't necessarily know how many textures you need to create, though, so the safest way to handle this is to write your own texture allocator. This can still be done within C# for what it's worth, MediaFoundation.NET has the interfaces defined that you'll need to use.</p>

<p>The allocator should maintain a list of "free" <code>SharpDX.Texture2D</code> objects - those that are not currently in use by the Sink Writer / encoder. Your program should be able to request new texture objects from the allocator, in which case it will either return an object from the free list, or create a new texture to accommodate the request.</p>

<p>The next problem is knowing when the <code>IMFSample</code> object has been discarded by the encoder, so that you can add the attached texture back to the free list. As it happens, the <code>MFCreateVideoSampleFromSurface</code> function you're currently using allocates samples that implement the <code>IMFTrackedSample</code> interface. You'll need that interface so that you can be notified when the sample is freed, so that you can reclaim the <code>Texture2D</code> objects.</p>

<p>The trick is that you have to tell the sample that <em>you</em> are the allocator. First, your allocator class needs to implement <code>IMFAsyncCallback</code>. If you set your allocator class on the sample via <code>IMFTrackedSample::SetAllocator</code>, your allocator's <code>IMFAsyncCallback::Invoke</code> method will be called, with an <code>IMFAsyncResult</code> passed as an argument whenever the encoder releases the sample. Here's a general example of what that allocator class could look like.
</p>

```sealed class TextureAllocator : IMFAsyncCallback, IDisposable
{
    private ConcurrentStack<SharpDX.Direct3D11.Texture2D> m_freeStack;
    private static readonly Guid s_IID_ID3D11Texture2D = new Guid("6f15aaf2-d208-4e89-9ab4-489535d34f9c");

    // If all textures are the exact same size and color format,
    // consider making those parameters private class members and
    // requiring they be specified as arguments to the constructor.
    public TextureAllocator()
    {
        m_freeStack = new ConcurrentStack<SharpDX.Direct3D11.Texture2D>();
    }

    private bool disposedValue = false;
    private void Dispose(bool disposing)
    {
        if(!disposedValue)
        {
            if(disposing)
            {
                // Dispose managed resources here
            }

            if(m_freeStack != null)
            {
                SharpDX.Direct3D11.Texture2D texture;
                while(m_freeStack.TryPop(out texture))
                {
                    texture.Dispose();
                }
                m_freeStack = null;
            }

            disposedValue = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~TextureAllocator()
    {
        Dispose(false);
    }

    private SharpDX.Direct3D11.Texture2D InternalAllocateNewTexture()
    {
        // Allocate a new texture with your format, size, etc here.
    }

    public SharpDX.Direct3D11.Texture2D AllocateTexture()
    {
        SharpDX.Direct3D11.Texture2D existingTexture;
        if(m_freeStack.TryPop(out existingTexture))
        {
            return existingTexture;
        }
        else
        {
            return InternalAllocateNewTexture();
        }
    }

    public IMFSample CreateSampleAndAllocateTexture()
    {
        IMFSample pSample;
        IMFTrackedSample pTrackedSample;
        HResult hr;

        // Create the video sample. This function returns an IMFTrackedSample per MSDN
        hr = MFExtern.MFCreateVideoSampleFromSurface(null, out pSample);
        MFError.ThrowExceptionForHR(hr);

        // Query the IMFSample to see if it implements IMFTrackedSample
        pTrackedSample = pSample as IMFTrackedSample;
        if(pTrackedSample == null)
        {
            // Throw an exception if we didn't get an IMFTrackedSample
            // but this shouldn't happen in practice.
            throw new InvalidCastException("MFCreateVideoSampleFromSurface returned a sample that did not implement IMFTrackedSample");
        }

        // Use our own class to allocate a texture
        SharpDX.Direct3D11.Texture2D availableTexture = AllocateTexture();
        // Convert the texture's native ID3D11Texture2D pointer into
        // an IUnknown (represented as as System.Object)
        object texNativeObject = Marshal.GetObjectForIUnknown(availableTexture.NativePointer);

        // Create the media buffer from the texture
        IMFMediaBuffer p2DBuffer;
        hr = MFExtern.MFCreateDXGISurfaceBuffer(s_IID_ID3D11Texture2D, texNativeObject, 0, false, out p2DBuffer);
        // Release the object-as-IUnknown we created above
        COMBase.SafeRelease(texNativeObject);
        // If media buffer creation failed, throw an exception
        MFError.ThrowExceptionForHR(hr);

        // Set the owning instance of this class as the allocator
        // for IMFTrackedSample to notify when the sample is released
        pTrackedSample.SetAllocator(this, null);

        // Attach the created buffer to the sample
        pTrackedSample.AddBuffer(p2DBuffer);

        return pTrackedSample;
    }

    // This is public so any textures you allocate but don't make IMFSamples
    // out of can be returned to the allocator manually.
    public void ReturnFreeTexture(SharpDX.Direct3D11.Texture2D freeTexture)
    {
        m_freeStack.Push(freeTexture);
    }

    // IMFAsyncCallback.GetParameters
    // This is allowed to return E_NOTIMPL as a way of specifying
    // there are no special parameters.
    public HResult GetParameters(out MFAsync pdwFlags, out MFAsyncCallbackQueue pdwQueue)
    {
        pdwFlags = MFAsync.None;
        pdwQueue = MFAsyncCallbackQueue.Standard;
        return HResult.E_NOTIMPL;
    }

    public HResult Invoke(IMFAsyncResult pResult)
    {
        object pUnkObject;
        IMFSample pSample = null;
        IMFMediaBuffer pBuffer = null;
        IMFDXGIBuffer pDXGIBuffer = null;

        // Get the IUnknown out of the IMFAsyncResult if there is one
        HResult hr = pResult.GetObject(out pUnkObject);
        if(Succeeded(hr))
        {
            pSample = pUnkObject as IMFSample;
        }

        if(pSample != null)
        {
            // Based on your implementation, there should only be one
            // buffer attached to one sample, so we can always grab the
            // first buffer. You could add some error checking here to make
            // sure the sample has a buffer count that is 1.
            hr = pSample.GetBufferByIndex(0, out pBuffer);
        }

        if(Succeeded(hr))
        {
            // Query the IMFMediaBuffer to see if it implements IMFDXGIBuffer
            pDXGIBuffer = pBuffer as IMFDXGIBuffer;
        }

        if(pDXGIBuffer != null)
        {
           // Got an IMFDXGIBuffer, so we can extract the internal
           // ID3D11Texture2D and make a new SharpDX.Texture2D wrapper.
           hr = pDXGIBuffer.GetResource(s_IID_ID3D11Texture2D, out pUnkObject);
        }

        if(Succeeded(hr))
        {
           // If we got here, pUnkObject is the native D3D11 Texture2D as
           // a System.Object, but it's unlikely you have an interface
           // definition for ID3D11Texture2D handy, so we can't just cast
           // the object to the proper interface.

           // Happily, SharpDX supports wrapping System.Object within
           // SharpDX.ComObject which makes things pretty easy.
           SharpDX.ComObject comWrapper = new SharpDX.ComObject(pUnkObject);

           // If this doesn't work, or you're using something like SlimDX
           // which doesn't support object wrapping the same way, the below
           // code is an alternative way.
           /*
           IntPtr pD3DTexture2D = Marshal.GetIUnknownForObject(pUnkObject);
           // Create your wrapper object here, like this for SharpDX
           SharpDX.ComObject comWrapper = new SharpDX.ComObject(pD3DTexture2D);
           // or like this for SlimDX
           SlimDX.Direct3D11.Texture2D.FromPointer(pD3DTexture2D);
           Marshal.Release(pD3DTexture2D);
           */

           // You might need to query comWrapper for a SharpDX.DXGI.Resource
           // first, then query that for the SharpDX.Direct3D11.Texture2D.
           SharpDX.Direct3D11.Texture2D texture = comWrapper.QueryInterface<SharpDX.Direct3D11.Texture2D>();
           if(texture != null)
           {
               // Now you can add "texture" back to the allocator's free list
               ReturnFreeTexture(texture);
           }
        }
    }
}
```

<p><hr/></p>

<h2>Setting <code>MF_SA_D3D_AWARE</code> on the Sink Writer input media type</h2>

<p>I don't think this is causing the bad <code>HRESULT</code> you're getting, but it isn't the right thing to do regardless. <code>MF_SA_D3D_AWARE</code> (and its DX11 counterpart, <code>MF_SA_D3D11_AWARE</code>) are attributes set by an <code>IMFTransform</code> object to inform you that the transform supports graphics acceleration via DX9 or DX11, respectively. There is no need to set this on the Sink Writer's input media type.
<hr/></p>

<h2>No <code>SafeRelease</code> on <code>texNativeObject</code></h2>

<p>I'd recommend calling <code>COMBase.SafeRelease()</code> on <code>texNativeObject</code> or you may leak memory. That, or you'll prolong the lifetime of that COM object unnecessarily until the GC cleans up the reference count for you
<hr/></p>

<h2>Unnecessary casting</h2>

<p>This is part of your code from above:</p>

```buffer = MFVideoEncoderST.ReinterpretCast<IMF2DBuffer,IMFMediaBuffer>(p2Dbuffer);
int length=0;
if (Succeeded(hr)) hr = (int)p2Dbuffer.GetContiguousLength(out length);
if (Succeeded(hr)) hr = (int)buffer.SetCurrentLength(length);
```

<p>I'm not sure what your <code>ReinterpretCast</code> function is doing, but if you <em>do</em> need to perform a <code>QueryInterface</code> style cast in C#, you can just use the <code>as</code> operator or a regular cast.</p>

```// pMediaBuffer is of type IMFMediaBuffer and has been created elsewhere
IMF2DBuffer p2DBuffer = pMediaBuffer as IMF2DBuffer;
if(p2DBuffer != null)
{
    // pMediaBuffer is an IMFMediaBuffer that also implements IMF2DBuffer
}
else
{
    // pMediaBuffer does not implement IMF2DBuffer
}
```

Title: MF SinkWriter Write Sample Failed

Body:
I'm trying to encode the ID3D11Texture2D to mp4 using MediaFoundation. Below is my current code.

Initializing Sink Writer

private int InitializeSinkWriter(String outputFile, int videoWidth, int videoHeight)
    {
        IMFMediaType mediaTypeIn = null;
        IMFMediaType mediaTypeOut = null;
        IMFAttributes attributes = null;

        int hr = 0;

        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateAttributes(out attributes, 1);
        if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 1);
        if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_LOW_LATENCY, 1);

        // Create the sink writer
        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateSinkWriterFromURL(outputFile, null, attributes, out sinkWriter);

        // Create the output type
        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateMediaType(out mediaTypeOut);
        if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video);
        if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_TRANSCODE_CONTAINERTYPE, MFTranscodeContainerType.MPEG4);
        if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.H264);
        if (Succeeded(hr)) hr = (int)mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AVG_BITRATE, videoBitRate);
        if (Succeeded(hr)) hr = (int)mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)MFVideoInterlaceMode.Progressive);

        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeSize(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight);
        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1);
        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
        if (Succeeded(hr)) hr = (int)sinkWriter.AddStream(mediaTypeOut, out streamIndex);

        // Create the input type
        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateMediaType(out mediaTypeIn);
        if (Succeeded(hr)) hr = (int)mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video);
        if (Succeeded(hr)) hr = (int)mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.ARGB32);
        if (Succeeded(hr)) hr = (int)mediaTypeIn.SetUINT32(MFAttributesClsid.MF_SA_D3D11_AWARE, 1);
        if (Succeeded(hr)) hr = (int)mediaTypeIn.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)MFVideoInterlaceMode.Progressive);
        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeSize(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight);
        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1);
        if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
        if (Succeeded(hr)) hr = (int)sinkWriter.SetInputMediaType(streamIndex, mediaTypeIn, null);

        // Start accepting data
        if (Succeeded(hr)) hr = (int)sinkWriter.BeginWriting();

        COMBase.SafeRelease(mediaTypeOut);
        COMBase.SafeRelease(mediaTypeIn);

        return hr;
    }

Writing frame

 int hr = 0;
        IMFSample sample = null;
        IMFMediaBuffer buffer = null;
        IMF2DBuffer p2Dbuffer = null;
        object texNativeObject = Marshal.GetObjectForIUnknown(surface.NativePointer);

        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateDXGISurfaceBuffer(new Guid("6f15aaf2-d208-4e89-9ab4-489535d34f9c"), texNativeObject, 0, false, out p2Dbuffer);

        buffer = MFVideoEncoderST.ReinterpretCast<IMF2DBuffer,IMFMediaBuffer>(p2Dbuffer);
        int length=0;
        if (Succeeded(hr)) hr = (int)p2Dbuffer.GetContiguousLength(out length);
        if (Succeeded(hr)) hr = (int)buffer.SetCurrentLength(length);

        if (Succeeded(hr)) hr = (int)MFExtern.MFCreateVideoSampleFromSurface(null, out sample);

        if (Succeeded(hr)) hr = (int)sample.AddBuffer(buffer);
        if (Succeeded(hr)) hr = (int)sample.SetSampleTime(prevRecordingDuration);
        if (Succeeded(hr)) hr = (int)sample.SetSampleDuration((recordDuration - prevRecordingDuration));

        if (Succeeded(hr)) hr = (int)sinkWriter.WriteSample(streamIndex, sample);

        COMBase.SafeRelease(sample);
        COMBase.SafeRelease(buffer);

using MFTRACE I'm getting the below error.

    02:48:04.99463 CMFSinkWriterDetours::WriteSample @024BEA18 Stream Index 0x0, Sample @17CEACE0, Time 571ms, Duration 16ms, Buffers 1, Size 4196352B,2088,2008 02:48:04.99465 CMFSinkWriterDetours::WriteSample @024BEA18 failed hr=0x887A0005 (null)2088,2008
02:48:05.01090 CMFSinkWriterDetours::WriteSample @024BEA18 Stream Index 0x0, Sample @17CE9FC0, Time 587ms, Duration 17ms, Buffers 1, Size 4196352B,2088,2008 02:48:05.01091 CMFSinkWriterDetours::WriteSample @024BEA18 failed hr=0x887A0005 (null)2088,2008
02:48:05.02712 CMFSinkWriterDetours::WriteSample @024BEA18 Stream Index 0x0, Sample @17CEACE0, Time 604ms, Duration 16ms, Buffers 1, Size 4196352B,2088,2008 02:48:05.02713 CMFSinkWriterDetours::WriteSample @024BEA18 failed hr=0x887A0005 (null)

Can anyone tell me whats wrong with my code? I can only produce 0 bytes of mp4 file.

Body:
There are a few potential problems that occur to me here. Roman mentioned the two big ones so I'll elaborate on those. I have a couple other critiques / suggestions for you as well.

Not using IMFDXGIDeviceManager

In order to use hardware acceleration within Media Foundation, you need to create a DirectX device manager object, either an IDirect3DDeviceManager9 for DX9 or in your case an IMFDXGIDeviceManager for DXGI. I strongly suggest reading all the MSDN documentation of that interface. The reason this is necessary is because the same DX device must be shared across all the cooperating hardware MF transforms being used, since they all need access to the shared GPU memory the device controls, and each one needs exclusive control of the device while it's working, so a locking system is needed. The device manager object provides that locking system, and is also the standard way of providing a DX device to one or more transforms. For DXGI, you create this using MFCreateDXGIDeviceManager.

From there, you need to create your DX11 device, and call IMFDXGIDeviceManager::ResetDevice with your DX11 device. You then need to set the device manager for the Sink Writer itself, which is not done in the code you provided above. That is accomplished like this:

// ... inside your InitializeSinkWriter function that you listed above

// I'm assuming you've already created and set up the DXGI device manager elsewhere
IMFDXGIDeviceManager pDeviceManager;

// Passing 3 as the argument because we're adding 3 attributes immediately, saves re-allocations
if (Succeeded(hr)) hr = (int)MFExtern.MFCreateAttributes(out attributes, 3);
if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 1);
if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_LOW_LATENCY, 1);

// Here's the key piece!
if (Succeeded(hr)) hr = (int)attributes.SetUnknown(MFAttributesClsid.MF_SINK_WRITER_D3D_MANAGER, pDeviceManager);

// Create the sink writer
if (Succeeded(hr)) hr = (int)MFExtern.MFCreateSinkWriterFromURL(outputFile, null, attributes, out sinkWriter);

This will actually enable D3D11 support for the hardware encoder and allow it access to read the Texture2D you're passing in. It's worth noting that MF_SINK_WRITER_D3D_MANAGER works for both DX9 and DXGI device managers.

Encoder buffering multiple IMFSample instances of the same texture

This is a potential cause of your problem as well - at the very least it will lead to a lot of unintended behavior even if it isn't the cause of the obvious problem. Building off Roman's comment, many encoders will buffer multiple frames as part of their encoding process. You don't see that behavior when using the Sink Writer because it handles all the detail work for you. However, what you are trying to accomplish (i.e. sending D3D11 textures as input frames) is sufficiently low level that you start having to worry about the internal details of the encoder MFT being used by the Sink Writer.

Most video encoder MFTs will use an internal buffer of some size to store the last N samples provided via IMFTransform::ProcessInput. This has the side effect that multiple samples must be provided as inputs before any output will be generated. Video encoders need access to multiple samples in order because they use the subsequent frames to determine how to encode the current frame. In other words, if the decoder is working on frame 0, it might need to see frames 1, 2, and 3 as well. From a technical standpoint, this is because of things like inter-frame prediction and motion estimation. Once the encoder is finished processing the oldest sample, it generates an output buffer (another IMFSample object, but this time on the output side via IMFTransform::ProcessOutput) then discards the input sample it was working on (by calling IUnknown::Release), then requests more input, and eventually moves on to the next frame. You can read more about this process in the MSDN article Processing Data in the Encoder

What this means, as Roman alluded to, is that you are encapsulating an ID3D11Texture2D inside an IMFMediaBuffer inside an IMFSample and then passing that to the Sink Writer. That sample is likely being buffered by the encoder as part of the encoding process. As the encoder is working, the contents of that Texture2D are probably changing, which can cause a variety of problems. Even if that didn't cause program errors, it would certainly lead to very strange encoded video outputs. Imagine if the encoder is trying to predict how the visual content of one frame changes in the next frame, and then the actual visual content of both frames is updated out from under the encoder!

This specific problem is happening because the encoder only has a pointer reference to your IMFSample instance, which is ultimately just a pointer itself to your ID3D11Texture2D object, and that object is a kind of pointer reference to mutable graphics memory. Ultimately, the contents of that graphics memory are changing due to some other part of your program, but because it's always the same GPU texture being updated, every single sample you send the encoder points to the same single texture. That means whenever you update the texture, by changing GPU memory, all the active IMFSample objects will reflect those changes, since they are all effectively pointing to the same GPU texture.

To fix this, you'll need to allocate multiple ID3D11Texture2D objects, such that you can pair up one texture with one IMFSample when providing it to the Sink Writer. This will fix the problem of all the samples pointing to the same single GPU texture by making each sample point to a unique texture. You won't necessarily know how many textures you need to create, though, so the safest way to handle this is to write your own texture allocator. This can still be done within C# for what it's worth, MediaFoundation.NET has the interfaces defined that you'll need to use.

The allocator should maintain a list of "free" SharpDX.Texture2D objects - those that are not currently in use by the Sink Writer / encoder. Your program should be able to request new texture objects from the allocator, in which case it will either return an object from the free list, or create a new texture to accommodate the request.

The next problem is knowing when the IMFSample object has been discarded by the encoder, so that you can add the attached texture back to the free list. As it happens, the MFCreateVideoSampleFromSurface function you're currently using allocates samples that implement the IMFTrackedSample interface. You'll need that interface so that you can be notified when the sample is freed, so that you can reclaim the Texture2D objects.

The trick is that you have to tell the sample that you are the allocator. First, your allocator class needs to implement IMFAsyncCallback. If you set your allocator class on the sample via IMFTrackedSample::SetAllocator, your allocator's IMFAsyncCallback::Invoke method will be called, with an IMFAsyncResult passed as an argument whenever the encoder releases the sample. Here's a general example of what that allocator class could look like.

sealed class TextureAllocator : IMFAsyncCallback, IDisposable
{
    private ConcurrentStack<SharpDX.Direct3D11.Texture2D> m_freeStack;
    private static readonly Guid s_IID_ID3D11Texture2D = new Guid("6f15aaf2-d208-4e89-9ab4-489535d34f9c");

    // If all textures are the exact same size and color format,
    // consider making those parameters private class members and
    // requiring they be specified as arguments to the constructor.
    public TextureAllocator()
    {
        m_freeStack = new ConcurrentStack<SharpDX.Direct3D11.Texture2D>();
    }

    private bool disposedValue = false;
    private void Dispose(bool disposing)
    {
        if(!disposedValue)
        {
            if(disposing)
            {
                // Dispose managed resources here
            }

            if(m_freeStack != null)
            {
                SharpDX.Direct3D11.Texture2D texture;
                while(m_freeStack.TryPop(out texture))
                {
                    texture.Dispose();
                }
                m_freeStack = null;
            }

            disposedValue = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~TextureAllocator()
    {
        Dispose(false);
    }

    private SharpDX.Direct3D11.Texture2D InternalAllocateNewTexture()
    {
        // Allocate a new texture with your format, size, etc here.
    }

    public SharpDX.Direct3D11.Texture2D AllocateTexture()
    {
        SharpDX.Direct3D11.Texture2D existingTexture;
        if(m_freeStack.TryPop(out existingTexture))
        {
            return existingTexture;
        }
        else
        {
            return InternalAllocateNewTexture();
        }
    }

    public IMFSample CreateSampleAndAllocateTexture()
    {
        IMFSample pSample;
        IMFTrackedSample pTrackedSample;
        HResult hr;

        // Create the video sample. This function returns an IMFTrackedSample per MSDN
        hr = MFExtern.MFCreateVideoSampleFromSurface(null, out pSample);
        MFError.ThrowExceptionForHR(hr);

        // Query the IMFSample to see if it implements IMFTrackedSample
        pTrackedSample = pSample as IMFTrackedSample;
        if(pTrackedSample == null)
        {
            // Throw an exception if we didn't get an IMFTrackedSample
            // but this shouldn't happen in practice.
            throw new InvalidCastException("MFCreateVideoSampleFromSurface returned a sample that did not implement IMFTrackedSample");
        }

        // Use our own class to allocate a texture
        SharpDX.Direct3D11.Texture2D availableTexture = AllocateTexture();
        // Convert the texture's native ID3D11Texture2D pointer into
        // an IUnknown (represented as as System.Object)
        object texNativeObject = Marshal.GetObjectForIUnknown(availableTexture.NativePointer);

        // Create the media buffer from the texture
        IMFMediaBuffer p2DBuffer;
        hr = MFExtern.MFCreateDXGISurfaceBuffer(s_IID_ID3D11Texture2D, texNativeObject, 0, false, out p2DBuffer);
        // Release the object-as-IUnknown we created above
        COMBase.SafeRelease(texNativeObject);
        // If media buffer creation failed, throw an exception
        MFError.ThrowExceptionForHR(hr);

        // Set the owning instance of this class as the allocator
        // for IMFTrackedSample to notify when the sample is released
        pTrackedSample.SetAllocator(this, null);

        // Attach the created buffer to the sample
        pTrackedSample.AddBuffer(p2DBuffer);

        return pTrackedSample;
    }

    // This is public so any textures you allocate but don't make IMFSamples
    // out of can be returned to the allocator manually.
    public void ReturnFreeTexture(SharpDX.Direct3D11.Texture2D freeTexture)
    {
        m_freeStack.Push(freeTexture);
    }

    // IMFAsyncCallback.GetParameters
    // This is allowed to return E_NOTIMPL as a way of specifying
    // there are no special parameters.
    public HResult GetParameters(out MFAsync pdwFlags, out MFAsyncCallbackQueue pdwQueue)
    {
        pdwFlags = MFAsync.None;
        pdwQueue = MFAsyncCallbackQueue.Standard;
        return HResult.E_NOTIMPL;
    }

    public HResult Invoke(IMFAsyncResult pResult)
    {
        object pUnkObject;
        IMFSample pSample = null;
        IMFMediaBuffer pBuffer = null;
        IMFDXGIBuffer pDXGIBuffer = null;

        // Get the IUnknown out of the IMFAsyncResult if there is one
        HResult hr = pResult.GetObject(out pUnkObject);
        if(Succeeded(hr))
        {
            pSample = pUnkObject as IMFSample;
        }

        if(pSample != null)
        {
            // Based on your implementation, there should only be one
            // buffer attached to one sample, so we can always grab the
            // first buffer. You could add some error checking here to make
            // sure the sample has a buffer count that is 1.
            hr = pSample.GetBufferByIndex(0, out pBuffer);
        }

        if(Succeeded(hr))
        {
            // Query the IMFMediaBuffer to see if it implements IMFDXGIBuffer
            pDXGIBuffer = pBuffer as IMFDXGIBuffer;
        }

        if(pDXGIBuffer != null)
        {
           // Got an IMFDXGIBuffer, so we can extract the internal
           // ID3D11Texture2D and make a new SharpDX.Texture2D wrapper.
           hr = pDXGIBuffer.GetResource(s_IID_ID3D11Texture2D, out pUnkObject);
        }

        if(Succeeded(hr))
        {
           // If we got here, pUnkObject is the native D3D11 Texture2D as
           // a System.Object, but it's unlikely you have an interface
           // definition for ID3D11Texture2D handy, so we can't just cast
           // the object to the proper interface.

           // Happily, SharpDX supports wrapping System.Object within
           // SharpDX.ComObject which makes things pretty easy.
           SharpDX.ComObject comWrapper = new SharpDX.ComObject(pUnkObject);

           // If this doesn't work, or you're using something like SlimDX
           // which doesn't support object wrapping the same way, the below
           // code is an alternative way.
           /*
           IntPtr pD3DTexture2D = Marshal.GetIUnknownForObject(pUnkObject);
           // Create your wrapper object here, like this for SharpDX
           SharpDX.ComObject comWrapper = new SharpDX.ComObject(pD3DTexture2D);
           // or like this for SlimDX
           SlimDX.Direct3D11.Texture2D.FromPointer(pD3DTexture2D);
           Marshal.Release(pD3DTexture2D);
           */

           // You might need to query comWrapper for a SharpDX.DXGI.Resource
           // first, then query that for the SharpDX.Direct3D11.Texture2D.
           SharpDX.Direct3D11.Texture2D texture = comWrapper.QueryInterface<SharpDX.Direct3D11.Texture2D>();
           if(texture != null)
           {
               // Now you can add "texture" back to the allocator's free list
               ReturnFreeTexture(texture);
           }
        }
    }
}

Setting MF_SA_D3D_AWARE on the Sink Writer input media type

I don't think this is causing the bad HRESULT you're getting, but it isn't the right thing to do regardless. MF_SA_D3D_AWARE (and its DX11 counterpart, MF_SA_D3D11_AWARE) are attributes set by an IMFTransform object to inform you that the transform supports graphics acceleration via DX9 or DX11, respectively. There is no need to set this on the Sink Writer's input media type.

No SafeRelease on texNativeObject

I'd recommend calling COMBase.SafeRelease() on texNativeObject or you may leak memory. That, or you'll prolong the lifetime of that COM object unnecessarily until the GC cleans up the reference count for you

Unnecessary casting

This is part of your code from above:

buffer = MFVideoEncoderST.ReinterpretCast<IMF2DBuffer,IMFMediaBuffer>(p2Dbuffer);
int length=0;
if (Succeeded(hr)) hr = (int)p2Dbuffer.GetContiguousLength(out length);
if (Succeeded(hr)) hr = (int)buffer.SetCurrentLength(length);

I'm not sure what your ReinterpretCast function is doing, but if you do need to perform a QueryInterface style cast in C#, you can just use the as operator or a regular cast.

// pMediaBuffer is of type IMFMediaBuffer and has been created elsewhere
IMF2DBuffer p2DBuffer = pMediaBuffer as IMF2DBuffer;
if(p2DBuffer != null)
{
    // pMediaBuffer is an IMFMediaBuffer that also implements IMF2DBuffer
}
else
{
    // pMediaBuffer does not implement IMF2DBuffer
}


问:
PXGraphExtension CreateInstance method?
How to create an instance of a graph extension something like:</p>

```<code>MyGraph_Extension graph = PXGraphExtension.CreateInstance<MyGraph_Extension>();
</code>```

答:
You do not create an instance for an extension graph the same way as the base graph. You use the instance of the base graph and just get your extension graph using GetExtension. Here is an example which is an extension for Sales order entry:

```<code>var baseGraph = PXGraph.CreateInstance<SOOrderEntry>();
var extGraph = baseGraph.GetExtension<SOOrderEntryExtension>();
</code>```

Title: PXGraphExtension CreateInstance method?

Body:
How to create an instance of a graph extension something like:

MyGraph_Extension graph = PXGraphExtension.CreateInstance<MyGraph_Extension>();

Body:
You do not create an instance for an extension graph the same way as the base graph. You use the instance of the base graph and just get your extension graph using GetExtension. Here is an example which is an extension for Sales order entry:

var baseGraph = PXGraph.CreateInstance<SOOrderEntry>();
var extGraph = baseGraph.GetExtension<SOOrderEntryExtension>();


问:
Sumif a certain value in column A equals the same value in the same Column
There are two columns with data I looked into the SUMIF() function but none seem to check for matching values within the same column. I cannot figure it out.

I want to sum column A with the same strings in column B. So add all the A, all the B and all the C. But without defining the strings.

答:
Assuming that you are not wanting to create a list of unique values found in column B first then I think this is all you need.</p>

```<code>=SUMIF($B$2:$B$9,B2,$A$2:$A$9)
</code>```

Body:
Assuming that you are not wanting to create a list of unique values found in column B first then I think this is all you need.

=SUMIF($B$2:$B$9,B2,$A$2:$A$9)


问:
How to add pre and post hooks in webpack watch mode when an update event happens?
For example, after I execute webpack --watch and everytime an update event E happens, I want:

before E: remove some files in some folder

after E: scan file names in some folder and write them to some files in some format.

All in all, execute some node code before and after E happens. Provided this config file.

```<code>module.exports = {

    output: {
        path: 'dist',
        publicPath: '/static/',
        filename:  "bundle.[hash].js",
    },

    module: {
        loaders: [
            {
                test: /\.css$/,
                loaders: ["style", "css"],
            },
        ],
    },
};
</code>```

答:
https://www.npmjs.com/package/webpack-shell-plugin</p>

```<code>This plugin allows you to run any shell commands before or after webpack builds. This will work for both webpack and webpack-dev-server.
</code>```

Body:
For example, after I execute webpack --watch and everytime an update event E happens, I want:

before E: remove some files in some folder

after E: scan file names in some folder and write them to some files in some format.

All in all, execute some node code before and after E happens. Provided this config file.

module.exports = {

    output: {
        path: 'dist',
        publicPath: '/static/',
        filename:  "bundle.[hash].js",
    },

    module: {
        loaders: [
            {
                test: /\.css$/,
                loaders: ["style", "css"],
            },
        ],
    },
};

Body:
https://www.npmjs.com/package/webpack-shell-plugin

This plugin allows you to run any shell commands before or after webpack builds. This will work for both webpack and webpack-dev-server.


问:
How can delay in program, until user response to run-time permission?
I have problem for run time permission.my code is:

```<code>     public class MainActivity extends AppCompatActivity {
int i = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
    ActivityCompat.requestPermissions(MainActivity.this, permissions, 0x3);
    while (i == 0) {
        //
    }
    //
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 0x3:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
              Toast.makeText(G.context, "allowed",Toast.LENGTH_LONG).show();
            } else {
               Toast.makeText(G.context, "deney", Toast.LENGTH_LONG).show();
            }
            break; } }}
</code>```

I want whlie block run after user response permission. but while block dont wait for permission result. How can delay in program, until user response to run-time permission, and after run whlie and another line?

答:
You just have to call the rest of your code if the "allowed" case of your onRequestPermissionResult method.</p>

```<code>if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
      Toast.makeText(G.context, "allowed",Toast.LENGTH_LONG).show();
      //The rest of your code
} else {
      Toast.makeText(G.context, "deney", Toast.LENGTH_LONG).show();
      //Ask again
}
</code>```

Body:
I have problem for run time permission.my code is:

     public class MainActivity extends AppCompatActivity {
int i = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
    ActivityCompat.requestPermissions(MainActivity.this, permissions, 0x3);
    while (i == 0) {
        //
    }
    //
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 0x3:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
              Toast.makeText(G.context, "allowed",Toast.LENGTH_LONG).show();
            } else {
               Toast.makeText(G.context, "deney", Toast.LENGTH_LONG).show();
            }
            break; } }}

I want whlie block run after user response permission. but while block dont wait for permission result. How can delay in program, until user response to run-time permission, and after run whlie and another line?

Body:
You just have to call the rest of your code if the "allowed" case of your onRequestPermissionResult method.

if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
      Toast.makeText(G.context, "allowed",Toast.LENGTH_LONG).show();
      //The rest of your code
} else {
      Toast.makeText(G.context, "deney", Toast.LENGTH_LONG).show();
      //Ask again
}