I am student of Computer engineering dept of YeungNam University in Korea.
First, sorry about my poor english skill.
I need help, please.
I found USB API for Java.
I need USB device's PID, VID and unique serial number because I need to do identify each USB device for my project(just mass storage device).
I use below example code.
(This is usb4java API example code.)
This code show me some information about USB HUDs, connected devices.
package org.usb4java.javax.examples;
import java.io.UnsupportedEncodingException;
import java.util.List;
import javax.usb.UsbConfiguration;
import javax.usb.UsbDevice;
import javax.usb.UsbDisconnectedException;
import javax.usb.UsbEndpoint;
import javax.usb.UsbException;
import javax.usb.UsbHostManager;
import javax.usb.UsbHub;
import javax.usb.UsbInterface;
import javax.usb.UsbPort;
import javax.usb.UsbServices;
/**
* Dumps all devices by using the javax-usb API.
*
* #author Klaus Reimer <k#ailis.de>
*/
public class DumpDevices
{
/**
* Dumps the specified USB device to stdout.
*
* #param device
* The USB device to dump.
*/
private static void dumpDevice(final UsbDevice device)
{
// Dump information about the device itself
System.out.println(device);
final UsbPort port = device.getParentUsbPort();
if (port != null)
{
System.out.println("Connected to port: " + port.getPortNumber());
System.out.println("Parent: " + port.getUsbHub());
}
// Dump device descriptor
System.out.println(device.getUsbDeviceDescriptor());
// Process all configurations
for (UsbConfiguration configuration: (List<UsbConfiguration>) device
.getUsbConfigurations())
{
// Dump configuration descriptor
System.out.println(configuration.getUsbConfigurationDescriptor());
// Process all interfaces
for (UsbInterface iface: (List<UsbInterface>) configuration
.getUsbInterfaces())
{
// Dump the interface descriptor
System.out.println(iface.getUsbInterfaceDescriptor());
// Process all endpoints
for (UsbEndpoint endpoint: (List<UsbEndpoint>) iface
.getUsbEndpoints())
{
// Dump the endpoint descriptor
System.out.println(endpoint.getUsbEndpointDescriptor());
}
}
}
System.out.println();
// Dump child devices if device is a hub
if (device.isUsbHub())
{
final UsbHub hub = (UsbHub) device;
for (UsbDevice child: (List<UsbDevice>) hub.getAttachedUsbDevices())
{
dumpDevice(child);
}
}
}
/**
* Main method.
*
* #param args
* Command-line arguments (Ignored)
* #throws UsbException
* When an USB error was reported which wasn't handled by this
* program itself.
*/
public static void main(final String[] args) throws UsbException
{
// Get the USB services and dump information about them
final UsbServices services = UsbHostManager.getUsbServices();
System.out.println("USB Service Implementation: "
+ services.getImpDescription());
System.out.println("Implementation version: "
+ services.getImpVersion());
System.out.println("Service API version: " + services.getApiVersion());
System.out.println();
// Dump the root USB hub
dumpDevice(services.getRootUsbHub());
}
}
and this code result like this:
USB Service Implementation: usb4java
Implementation version: 1.2.0
Service API version: 1.0.2
usb4java root hub 1.0.0
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.01
bDeviceClass 9 Hub
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0xffff
idProduct 0xffff
bcdDevice 0.00
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 18
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
bMaxPower 0mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 9 Hub
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Bus 002 Device 007: ID 203a:fffa
Connected to port: 1
Parent: usb4java root hub 1.0.0
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 Per Interface
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x203a
idProduct 0xfffa
bcdDevice 1.00
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 25
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 1
bmAttributes 0xc0
Self Powered
bMaxPower 0mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 7 Printer
bInterfaceSubClass 1
bInterfaceProtocol 1
iInterface 4
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 512
bInterval 0
.
.
.
.
Bus 002 Device 003: ID 152d:2329
Connected to port: 3
Parent: usb4java root hub 1.0.0
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 Per Interface
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x152d
idProduct 0x2329
bcdDevice 1.00
iManufacturer 1
iProduct 2
iSerial 5
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 32
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 4
bmAttributes 0xc0
Self Powered
bMaxPower 2mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 8 Mass Storage
bInterfaceSubClass 6
bInterfaceProtocol 80
iInterface 6
.
.
.
.
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 512
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 512
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 512
bInterval 0
In result of code, there is mass storage and I can see PID and VID, but there is iserialnumber(index of serial number in device descriptor) instead of real serialnumber.
I think that to identify each USB mass storage device, need combination of PID, VID, S/N.
How can I get serial number?
In Usb4Java, Javax.usb, libusb, these APIs not include methods like 'getSerialnumber()'.
Help me please.
The "iSerial" is the index of the version string in the device's string table. You can retrieve the corresponding string using the getString(byte) method on the device. Same thing goes for "iManufacturer" and "iProduct".
Keep in mind that not all devices will have a unique serial number.
Related
I am running into a weird problem when reading CAC card, in a multi terminal setup, from Nth (Except 1st) terminal.
Environment - JDK8_u211, Destop without any card reader, Internal card reader for laptop, USB card reader, CAC\PIV card
USE-CASE Tried
When the CAC card is plugged into internal slot of Laptop, everything works fine with and withou USB card terminal connected to laptop.
When the CAC card is plugged into the USB reader and connected to the Desktop, everything works fine.
When the CAC card is plugged into the USB reader and connected to the Laptop, the PKCS store instantiation fails, as the config uses slot=1
When the CAC card is plugged into the USB reader and connected to the Laptop, if I hard code slot=4 in the config, everything works fine.
Problem: Unable to determine the correct slot to use within the config file. Somehow number of terminals is not adding up to determine the slot at runtime.
By enabling JDK debug logs, i could verify that internally "C_GetSlotList" returns 0,4 where as I have only 2 terminals, hence using index 0 or 1.
Does anyone know how to determine the correlation between terminal vs slot or is there something really wrong in the way i am trying to read the card ?
Please advise.
Sample code
public class MultipleTerminals {
private static String DLL_PATH = "C:\\opensc-pkcs11.dll";
public static void main(String[] args) throws Exception {
MyTerminal custTerminalObj = getSmartCardTerminal();
CardTerminal terminal = custTerminalObj.getTerminal();
Integer terminalIdx = custTerminalObj.getIndex();
System.out.println("Using Terminal.Name: " + terminal.getName());
System.out.println("Using Terminal.isCardPresent: " + ((CardTerminal)terminal).isCardPresent());
if (terminal.isCardPresent()) { // duplicate check
registerProvider(4);
KeyStore keyStore = createKeyStore();
printCertificate(keyStore);
}
}
public static MyTerminal getSmartCardTerminal() {
System.out.println("---------------------------------------------------");
MyTerminal terminal = null;
int terminalIdx = -1;
try {
TerminalFactory factory = TerminalFactory.getDefault();
if (factory != null) {
List<CardTerminal> allTerminals = factory.terminals().list();
for(CardTerminal term : allTerminals) {
System.out.println("Terminal Name: " + term.getName());
System.out.println("isCardPresent: " + term.isCardPresent());
System.out.println("----------");
}
for(CardTerminal term : allTerminals) {
terminalIdx++;
if(term.isCardPresent()) {
terminal = new MyTerminal();
terminal.setIndex(terminalIdx);
terminal.setTerminal(term);
System.out.println("Using Terminal Idx: " + terminalIdx);
}
}
}
} catch (CardException e1) {
terminal = null;
System.out.println("SmartCardHelper.getSmartCardTerminal --> "
+ "Exception while accessing smart-card terminal: "
+ e1.getMessage());
e1.printStackTrace();
}
return terminal;
}
public static void registerProvider(Integer idx) {
System.out.println("---------------------------------------------------");
String ext = "attributes(*,*,*)=\n{\nCKA_TOKEN=true\nCKA_LOCAL=true\n}";
String OPENSC_DEFAULT_PROVIDER_NAME = "PKCS#11";
String OPENSC_PKCS11_DLL = DLL_PATH;
String configString = "name = "
+ OPENSC_DEFAULT_PROVIDER_NAME.replace(' ', '_') + "\n"
+ "library = "
+ OPENSC_PKCS11_DLL + "\n slot = " + idx + " "
+ "\n attributes = compatibility \n" + ext;
System.out.println("\tConfigString: " + configString);
ByteArrayInputStream is = new ByteArrayInputStream(
configString.getBytes(Charset.defaultCharset()));
Provider cardSecurityProvider = new sun.security.pkcs11.SunPKCS11(
is);
displayProviders();
Security.addProvider(cardSecurityProvider);
displayProviders();
System.out.println("==================");
}
public static KeyStore createKeyStore() throws KeyStoreException {
KeyStore.CallbackHandlerProtection callbackHandler = new KeyStore.CallbackHandlerProtection(
new PIVCardPinHandler());
KeyStore.Builder builder = KeyStore.Builder.newInstance("PKCS11", null,
callbackHandler);
return builder.getKeyStore();
}
public static void displayProviders() {
System.out.println("---------------------------------------------------");
Provider[] objs = Security.getProviders();
System.out.println("Provider Count: " + objs.length);
String type = "KeyStore";
String algorithm="PKCS11";
ProviderList list = Providers.getProviderList();
Provider provider = list.getProvider("SunPKCS11-PKCS");
System.out.println("Provider[SunPKCS11-PKCS]: " + provider);
if(provider != null) {
Set<Service> svcs = provider.getServices();
System.out.println("Service count: " + svcs.size());
}
Service firstService = list.getService(type, algorithm);
System.out.println("Type[KeyStore], Algo[PKCS11], Service: " + firstService);
}
public static void printCertificate(KeyStore keyStore)
throws KeyStoreException {
for (String alias : Collections.list(keyStore.aliases())) {
System.out.println("Alias: " + alias);
}
}
}
class MyTerminal{
private Integer index;
private CardTerminal terminal;
public MyTerminal() {
}
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public CardTerminal getTerminal() {
return terminal;
}
public void setTerminal(CardTerminal terminal) {
this.terminal = terminal;
}
}
* Output TestCase-1 (WORKING)*
---------------------------------------------------
Terminal Name: Alcor Micro USB Smart Card Reader 0
isCardPresent: true
----------
Terminal Name: Identive SCR33xx v2.0 USB SC Reader 0
isCardPresent: false
----------
Using Terminal Idx: 0
Using Terminal.Name: Alcor Micro USB Smart Card Reader 0
Using Terminal.isCardPresent: true
---------------------------------------------------
ConfigString:
name = PKCS#11
library = C:\opensc-pkcs11.dll
slot = 0
attributes = compatibility
attributes(*,*,*)=
{
CKA_TOKEN=true
CKA_LOCAL=true
}
SunPKCS11 loading ---DummyConfig-1---
sunpkcs11: Initializing PKCS#11 library C:\opensc-pkcs11.dll
Information for provider SunPKCS11-PKCS
Library info:
cryptokiVersion: 2.20
manufacturerID: DUMMY_VALUE
flags: 0
libraryDescription: DUMMY_VALUE
libraryVersion: 0.19
All slots: 0, 4
Slots with tokens: 0, 4
Slot info for slot 0:
slotDescription: Alcor Micro USB Smart Card Reader 0
manufacturerID: DUMMY_VALUE
flags: CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT
hardwareVersion: 0.00
firmwareVersion: 0.00
Token info for token in slot 0:
label: DUMMY_VALUE
manufacturerID: DUMMY_VALUE
model: PKCS#15 emulated
serialNumber: DUMMY_VALUE
flags: CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED
ulMaxSessionCount: CK_EFFECTIVELY_INFINITE
ulSessionCount: 0
ulMaxRwSessionCount: CK_EFFECTIVELY_INFINITE
ulRwSessionCount: 0
ulMaxPinLen: 8
ulMinPinLen: 4
ulTotalPublicMemory: CK_UNAVAILABLE_INFORMATION
ulFreePublicMemory: CK_UNAVAILABLE_INFORMATION
ulTotalPrivateMemory: CK_UNAVAILABLE_INFORMATION
ulFreePrivateMemory: CK_UNAVAILABLE_INFORMATION
hardwareVersion: 0.00
firmwareVersion: 0.00
utcTime:
---------------------------------------------------
Provider Count: 10
Provider[SunPKCS11-PKCS]: null
Type[KeyStore], Algo[PKCS11], Service: null
---------------------------------------------------
Provider Count: 11
Provider[SunPKCS11-PKCS]: SunPKCS11-PKCS version 1.8
Service count: 26
Type[KeyStore], Algo[PKCS11], Service: SunPKCS11-PKCS: KeyStore.PKCS11 -> sun.security.pkcs11.P11KeyStore
aliases: [PKCS11-PKCS]
(KeyStore)
==================
sunpkcs11: caller passed NULL pin
* Output TestCase-3 (NOT WORKING)*
---------------------------------------------------
Terminal Name: Alcor Micro USB Smart Card Reader 0
isCardPresent: false
----------
Terminal Name: Identive SCR33xx v2.0 USB SC Reader 0
isCardPresent: true
----------
Using Terminal Idx: 1
Using Terminal.Name: Identive SCR33xx v2.0 USB SC Reader 0
Using Terminal.isCardPresent: true
---------------------------------------------------
ConfigString:
name = PKCS#11
library = C:\opensc-pkcs11.dll
slot = 1
attributes = compatibility
attributes(*,*,*)=
{
CKA_TOKEN=true
CKA_LOCAL=true
}
SunPKCS11 loading ---DummyConfig-1---
sunpkcs11: Initializing PKCS#11 library C:\opensc-pkcs11.dll
Information for provider SunPKCS11-PKCS
Library info:
cryptokiVersion: 2.20
manufacturerID: DUMMY_VALUE
flags: 0
libraryDescription: DUMMY_VALUE
libraryVersion: 0.19
All slots: 0, 4
Slots with tokens: 0, 4
---------------------------------------------------
Provider Count: 10
Provider[SunPKCS11-PKCS]: null
Type[KeyStore], Algo[PKCS11], Service: null
---------------------------------------------------
Provider Count: 11
Provider[SunPKCS11-PKCS]: SunPKCS11-PKCS version 1.8
Service count: 0
Type[KeyStore], Algo[PKCS11], Service: null
==================
Exception in thread "main" java.security.KeyStoreException: KeyStore instantiation failed
at java.security.KeyStore$Builder$2.getKeyStore(KeyStore.java:1967)
Caused by: java.security.KeyStoreException: PKCS11 not found
at java.security.KeyStore.getInstance(KeyStore.java:851)
at java.security.KeyStore$Builder$2$1.run(KeyStore.java:1923)
at java.security.KeyStore$Builder$2$1.run(KeyStore.java:1918)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.KeyStore$Builder$2.getKeyStore(KeyStore.java:1964)
... 2 more
Caused by: java.security.NoSuchAlgorithmException: PKCS11 KeyStore not available
at sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
at java.security.Security.getImpl(Security.java:695)
at java.security.KeyStore.getInstance(KeyStore.java:848)
... 6 more
* Output TestCase-4 (WORKING)*
---------------------------------------------------
Terminal Name: Alcor Micro USB Smart Card Reader 0
isCardPresent: false
----------
Terminal Name: Identive SCR33xx v2.0 USB SC Reader 0
isCardPresent: true
----------
Using Terminal Idx: 1
Using Terminal.Name: Identive SCR33xx v2.0 USB SC Reader 0
Using Terminal.isCardPresent: true
---------------------------------------------------
ConfigString:
name = PKCS#11
library = C:\opensc-pkcs11.dll
slot = 4
attributes = compatibility
attributes(*,*,*)=
{
CKA_TOKEN=true
CKA_LOCAL=true
}
SunPKCS11 loading ---DummyConfig-1---
sunpkcs11: Initializing PKCS#11 library C:\opensc-pkcs11.dll
Information for provider SunPKCS11-PKCS
Library info:
cryptokiVersion: DUMMY_VALUE
manufacturerID: DUMMY_VALUE
flags: 0
libraryDescription: DUMMY_VALUE
libraryVersion: DUMMY_VALUE
All slots: 0, 4
Slots with tokens: 0, 4
Slot info for slot 4:
slotDescription: DUMMY_VALUE
manufacturerID: DUMMY_VALUE
flags: CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT
hardwareVersion: 0.00
firmwareVersion: 0.00
Token info for token in slot 4:
label: DUMMY_LABEL
manufacturerID: DUMMY_VALUE
model: PKCS#15 emulated
serialNumber: DUMMY_VALUE
flags: CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED
ulMaxSessionCount: CK_EFFECTIVELY_INFINITE
ulSessionCount: 0
ulMaxRwSessionCount: CK_EFFECTIVELY_INFINITE
ulRwSessionCount: 0
ulMaxPinLen: 8
ulMinPinLen: 4
ulTotalPublicMemory: CK_UNAVAILABLE_INFORMATION
ulFreePublicMemory: CK_UNAVAILABLE_INFORMATION
ulTotalPrivateMemory: CK_UNAVAILABLE_INFORMATION
ulFreePrivateMemory: CK_UNAVAILABLE_INFORMATION
hardwareVersion: 0.00
firmwareVersion: 0.00
utcTime:
---------------------------------------------------
Provider Count: 10
Provider[SunPKCS11-PKCS]: null
Type[KeyStore], Algo[PKCS11], Service: null
---------------------------------------------------
Provider Count: 11
Provider[SunPKCS11-PKCS]: SunPKCS11-PKCS version 1.8
Service count: 26
Type[KeyStore], Algo[PKCS11], Service: SunPKCS11-PKCS: KeyStore.PKCS11 -> sun.security.pkcs11.P11KeyStore
aliases: [PKCS11-PKCS]
(KeyStore)
==================
sunpkcs11: caller passed NULL pin
You are getting confused between slot id and slot index. They are two different attributes.
The C_GetSlotList gives you an array of slot id's not slot indexes. In your case 0 and 4 are slot id's, not slot indexes. The slot index is the index of the slot id in the array.
In your getSmartCardTerminal() method where you are identifying the terminalIdx you are identifying the index, but in your registerProvider(Integer idx) method you are mapping the index as the id, here:
OPENSC_PKCS11_DLL + "\n slot = " + idx + " "
When you are using the slot index you should be using slotListIndex and when you are using the slot id, you should be using slot.
So to fix your problem change it to:
OPENSC_PKCS11_DLL + "\n slotListIndex = " + idx + " "
Documentation here.
I'm trying to show a pdf in android app. The response I get from the server is looking like this. I convert it to input stream and pass it to pdf viewer library
%PDF-1.4 %ÓôÌá 1 0 obj << /CreationDate(D:20180403085232+02'00')
/Creator(PDFsharp 1.32.3057-g (www.pdfsharp.net)) /Producer(PDFsharp
1.32.3057-g (www.pdfsharp.net))
endobj 2 0 obj << /Type/Catalog /Pages 3 0 R
endobj 3 0 obj << /Type/Pages /Count 3 /Kids[4 0 R 8 0 R 11 0 R]
endobj 4 0 obj << /Type/Page /MediaBox[0 0 612 792] /Parent 3 0 R /Contents 5 0 R /Resources << /ProcSet
[/PDF/Text/ImageB/ImageC/ImageI] /XObject << /I0 6 0 R
/ExtGState << /GS0 7 0 R
/Group << /CS/DeviceRGB /S/Transparency /I false /K false
endobj 5 0 obj << /Length 260 /Filter/FlateDecode
stream xœíRMK1½÷Wä˜M“&Mî¢àa]oâIEDF‚¿ÞÌ̺²ø¥”4y¯—´C©#¹ŽÆЃáú!ÏDpñZ†2€š
W9#¾gNŽa“/…à4÷}©gåòŠàf§{¾.«õ–àWìÚ¡WÆT4Bµ
†¡O·e[F>g^í=|UEw‡ª‚Ö$å(U‘ôÇ›„L¶ÜÑ™—~¤6•š'Ú9f”Pz›PŽ€¦¨"бv_gly›Û÷Mä~.î]
™Ûë؈?œå€«Ul¡À™y_6þ»Aÿ—ÿ¤|èYòÿX`ìfÈ»ï³ÉõŠ¹·ò endstream endobj 6 0
obj << /Type/XObject /Subtype/Image /Length 5097196
/Filter/FlateDecode /Width 2511 /Height 3531 /BitsPerComponent 8
/ColorSpace/DeviceRGB /Interpolate true
stream xœìÝ œ¤g]'ðïé9rÂáˆJAE%€ Š"ë‚FQ0 Ë!º» ¢‚+^ (h
This is my code:
// get the response as string
val body = response.body?.string()
// convert it to inputstream
val inputStream = ByteArrayInputStream(body.toByteArray(Charsets.UTF_8))
// load it wil pdf viewer
pdf_viewer.fromStream(inputStream).load()
Everything till the last line is ok. I got init FPDF library but there is nothing on the screen. It stays with white background.
If I open the pdf standalone I can see that everything is fine.
I'm using
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
here is the xml file
<com.github.barteksc.pdfviewer.PDFView
android:id="#+id/pdf_viewer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
EDIT:
the working solution was to get the bytes and pass them to PDFViewer
val bodyBytes: ByteArray = response.body!!.bytes()
runOnUiThread {
pdf_viewer.fromBytes(bodyBytes).enableSwipe(true) // allows to block changing pages using swipe
.swipeHorizontal(false)
.enableDoubletap(true)
.defaultPage(0)
.enableAnnotationRendering(false) // render annotations (such as comments, colors or forms)
.password(null)
.scrollHandle(null)
.enableAntialiasing(true) // improve rendering a little bit on low-res screens
// spacing between pages in dp. To define spacing color, set view background
.spacing(0)
.invalidPageColor(Color.WHITE) // color of page that is invalid and cannot be loaded
.load()
}
I have a system with HTTP POST requests and it runs with Spring 5 (standalone tomcat). In short it looks like this:
client (Apache AB) ----> micro service (java or golang) --> RabbitMQ --> Core(spring + tomcat).
The thing is, when I use my Java (Spring) service, it is ok. AB shows this output:
ab -n 1000 -k -s 2 -c 10 -s 60 -p test2.sh -A 113:113 -T 'application/json' https://127.0.0.1:8449/SecureChat/chat/v1/rest-message/send
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
...
Completed 1000 requests
Finished 1000 requests
Server Software:
Server Hostname: 127.0.0.1
Server Port: 8449
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256
Document Path: /rest-message/send
Document Length: 39 bytes
Concurrency Level: 10
Time taken for tests: 434.853 seconds
Complete requests: 1000
Failed requests: 0
Keep-Alive requests: 0
Total transferred: 498000 bytes
Total body sent: 393000
HTML transferred: 39000 bytes
Requests per second: 2.30 [#/sec] (mean)
Time per request: 4348.528 [ms] (mean)
Time per request: 434.853 [ms] (mean, across all concurrent
requests)
Transfer rate: 1.12 [Kbytes/sec] received
0.88 kb/s sent
2.00 kb/s total
Connection Times (ms)
min mean[+/-sd] median max
Connect: 4 14 7.6 17 53
Processing: 1110 4317 437.2 4285 8383
Waiting: 1107 4314 437.2 4282 8377
Total: 1126 4332 436.8 4300 8403
That is through TLS.
But when I try to use my Golang service I get timeout:
Benchmarking 127.0.0.1 (be patient)...apr_pollset_poll: The timeout specified has expired (70007)
Total of 92 requests completed
And this output:
ab -n 100 -k -s 2 -c 10 -s 60 -p test2.sh -T 'application/json' http://127.0.0.1:8089/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)...^C
Server Software:
Server Hostname: 127.0.0.1
Server Port: 8089
Document Path: /
Document Length: 39 bytes
Concurrency Level: 10
Time taken for tests: 145.734 seconds
Complete requests: 92
Failed requests: 1
(Connect: 0, Receive: 0, Length: 1, Exceptions: 0)
Keep-Alive requests: 91
Total transferred: 16380 bytes
Total body sent: 32200
HTML transferred: 3549 bytes
Requests per second: 0.63 [#/sec] (mean)
Time per request: 15840.663 [ms] (mean)
Time per request: 1584.066 [ms] (mean, across all concurrent requests)
Transfer rate: 0.11 [Kbytes/sec] received
0.22 kb/s sent
0.33 kb/s total
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 1229 1494 1955.9 1262 20000
Waiting: 1229 1291 143.8 1262 2212
Total: 1229 1494 1955.9 1262 20000
That is through plane tcp.
I guess I have some mistakes in my code. I made it in one file
func initAmqp(rabbitUrl string) {
var err error
conn, err = amqp.Dial(rabbitUrl)
failOnError(err, "Failed to connect to RabbitMQ")
}
func main() {
err := gcfg.ReadFileInto(&cfg, "config.gcfg")
if err != nil {
log.Fatal(err);
}
PrintConfig(cfg)
if cfg.Section_rabbit.RabbitUrl != "" {
initAmqp(cfg.Section_rabbit.RabbitUrl);
}
mux := http.NewServeMux();
mux.Handle("/", NewLimitHandler(1000, newTestHandler()))
server := http.Server {
Addr: cfg.Section_basic.Port,
Handler: mux,
ReadTimeout: 20 * time.Second,
WriteTimeout: 20 * time.Second,
}
defer conn.Close();
log.Println(server.ListenAndServe());
}
func NewLimitHandler(maxConns int, handler http.Handler) http.Handler {
h := &limitHandler{
connc: make(chan struct{}, maxConns),
handler: handler,
}
for i := 0; i < maxConns; i++ {
h.connc <- struct{}{}
}
return h
}
func newTestHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handler(w, r);
})
}
func handler(w http.ResponseWriter, r *http.Request) {
if b, err := ioutil.ReadAll(r.Body); err == nil {
fmt.Println("message is ", string(b));
res := publishMessages(string(b))
w.Write([]byte(res))
w.WriteHeader(http.StatusOK)
counter ++;
}else {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("500 - Something bad happened!"))
}
}
func publishMessages(payload string) string {
ch, err := conn.Channel()
failOnError(err, "Failed to open a channel")
q, err = ch.QueueDeclare(
"", // name
false, // durable
false, // delete when unused
true, // exclusive
false, // noWait
nil, // arguments
)
failOnError(err, "Failed to declare a queue")
msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
failOnError(err, "Failed to register a consumer")
corrId := randomString(32)
log.Println("corrId ", corrId)
err = ch.Publish(
"", // exchange
cfg.Section_rabbit.RabbitQeue, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
DeliveryMode: amqp.Transient,
ContentType: "application/json",
CorrelationId: corrId,
Body: []byte(payload),
Timestamp: time.Now(),
ReplyTo: q.Name,
})
failOnError(err, "Failed to Publish on RabbitMQ")
defer ch.Close();
result := "";
for d := range msgs {
if corrId == d.CorrelationId {
failOnError(err, "Failed to convert body to integer")
log.Println("result = ", string(d.Body))
return string(d.Body);
}else {
log.Println("waiting for result = ")
}
}
return result;
}
Can someone help?
EDIT
here are my variables
type limitHandler struct {
connc chan struct{}
handler http.Handler
}
var conn *amqp.Connection
var q amqp.Queue
EDIT 2
func (h *limitHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
select {
case <-h.connc:
fmt.Println("ServeHTTP");
h.handler.ServeHTTP(w, req)
h.connc <- struct{}{}
default:
http.Error(w, "503 too busy", http.StatusServiceUnavailable)
}
}
EDIT 3
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
panic(fmt.Sprintf("%s: %s", msg, err))
}
}
I get a pca-model
> library(sparklyr)
> library(dplyr)
> sc <- spark_connect("local", version="2.0.0")
> iris_tbl <- copy_to(sc, iris, "iris", overwrite = TRUE)
The following columns have been renamed:
- 'Sepal.Length' => 'Sepal_Length' (#1)
- 'Sepal.Width' => 'Sepal_Width' (#2)
- 'Petal.Length' => 'Petal_Length' (#3)
- 'Petal.Width' => 'Petal_Width' (#4)
> pca_model <- tbl(sc, "iris") %>%
+ select(-Species) %>%
+ ml_pca()
> print(pca_model)
Explained variance:
PC1 PC2 PC3 PC4
0.924618723 0.053066483 0.017102610 0.005212184
Rotation:
PC1 PC2 PC3 PC4
Sepal_Length -0.36138659 -0.65658877 0.58202985 0.3154872
Sepal_Width 0.08452251 -0.73016143 -0.59791083 -0.3197231
Petal_Length -0.85667061 0.17337266 -0.07623608 -0.4798390
Petal_Width -0.35828920 0.07548102 -0.54583143 0.7536574
But can`t use the resulting model to forecast.
sdf_predict(pca_model)
Source: query [?? x 6]
Database: spark connection master=local[4] app=sparklyr local=TRUE
Ends with an error
java.lang.IllegalArgumentException: requirement failed:
The columns of A don't match the number of elements of x. A: 4, x: 0
Inserting data for the forecast does not help
sdf_predict(pca_model, tbl(sc, "iris") %>% select(-Species))
Source: query [?? x 5]
Database: spark connection master=local[4] app=sparklyr local=TRUE
Ends with an error
java.lang.IllegalArgumentException: requirement failed:
The columns of A don't match the number of elements of x. A: 4, x: 0
It is generally possible to use PCA to predict in spark?
Instead of sdf_predict, use sdf_project.
> pca_projected <- sdf_project(pca_model, tbl(sc, "iris") %>% select(-Species),
+ features=rownames(pca_model$components))
> pca_projected %>% collect %>% head
# A tibble: 6 x 8
Sepal_Length Sepal_Width Petal_Length Petal_Width PC1 PC2 PC3 PC4
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 5.10 3.50 1.40 0.200 -2.82 -5.65 0.660 -0.0311
2 4.90 3.00 1.40 0.200 -2.79 -5.15 0.842 0.0657
3 4.70 3.20 1.30 0.200 -2.61 -5.18 0.614 -0.0134
4 4.60 3.10 1.50 0.200 -2.76 -5.01 0.600 -0.109
5 5.00 3.60 1.40 0.200 -2.77 -5.65 0.542 -0.0946
6 5.40 3.90 1.70 0.400 -3.22 -6.07 0.463 -0.0576
I am behind the NAT of my WiFi router. When I send a packet from port 20,000,it comes out of my WiFi router on port 56867. I want to be able to get the output port number (the 56867) programmatically and I am trying do so via the STUN protocol.
I am using the STUN client code in package "com.sun.stun" at https://code.google.com/p/openwonderland-jvoicebridge/source/browse/branches/jp/stun/src/com/sun/stun/StunClient.java . I tried using the STUN client code to get my external IP address and port number by writing the following code:
import com.sun.stun.*;
import java.net.*;
public class Main {
public static void main(String args[]) throws Exception {
InetSocketAddress ii = new InetSocketAddress("stun.ekiga.net", 3478);
DatagramSocket s = new DatagramSocket();
System.out.println("LocalAddress(): " + s.getLocalAddress());
System.out.println("LocalPort(): " + s.getLocalPort());
s.setSoTimeout(10000);
StunClient stunClient1 = new StunClient(ii, s);
System.out.println("external InetAddress/Port: " + stunClient1.getMappedAddress().toString());
}
}
My output looks like this:
run:
LocalAddress(): 0.0.0.0/0.0.0.0
LocalPort(): 32979
May 30, 2015 11:38:16 PM unmodified.com.sun.stun.StunClient run
INFO: using STUN server stun.ekiga.net/217.10.68.152:3478
external InetAddress/Port: /0.0.0.0:32979
BUILD SUCCESSFUL (total time: 0 seconds)
The problem is that stunClient1.getMappedAddress() is giving me the binding address and ephemeral port number of DatagramSocket s and I want to get my public ip and public port number. Please help.
* Explaination / Clarification *
When I create a DatagramSocket, the OS/Java assigns it an ephemeral port number, in this case 58100. I have a Wifi router that has NAT. When I send a packet through my router to stun.ekiga.net, the external port number that stun.ekiga.net is sending its response back to is not the same as the the internal port number. I want the external port number that the STUN server is replying to.
* Helpful information *
I have received the following STUN packet:
Length of response is: 88 bytes
STUN response type received: 257 [StunHeader.BINDING_RESPONSE]
STUN response packet in binary format:
00000001::00000001::00000000::01000100::11011100::00001110::00110110::10101000::11011100::00001110::00110110::10101000::11011100::00001110::00110110::10101000::11011100::00001110::00110110::10101000::00000000::00000001::00000000::00001000::00000000::00000001::10000000::00010100::00000000::00000000::00000000::00000000::00000000::00000100::00000000::00001000::00000000::00000001::00001101::10010110::11011001::00001010::01000100::10011000::00000000::00000101::00000000::00001000::00000000::00000001::00001101::10010111::11011001::01110100::01111010::10001010::10000000::00100000::00000000::00001000::00000000::00000001::01011100::00011010::11011100::00001110::00110110::10101000::10000000::00100010::00000000::00010000::01010110::01101111::01110110::01101001::01100100::01100001::00101110::01101111::01110010::01100111::00100000::00110000::00101110::00111001::00110110::00000000::
STUN response packet in hexadecimal format:
01:01:00:44:DC:0E:36:A8:DC:0E:36:A8:DC:0E:36:A8:DC:0E:36:A8:00:01:00:08:00:01:80:14:00:00:00:00:00:04:00:08:00:01:0D:96:D9:0A:44:98:00:05:00:08:00:01:0D:97:D9:74:7A:8A:80:20:00:08:00:01:5C:1A:DC:0E:36:A8:80:22:00:10:56:6F:76:69:64:61:2E:6F:72:67:20:30:2E:39:36:00:
STUN response packet in decimal format:
1 : 1 : 0 : 68 : -36 : 14 : 54 : -88 : -36 : 14 : 54 : -88 : -36 : 14 : 54 : -88 : -36 : 14 : 54 : -88 : 0 : 1 : 0 : 8 : 0 : 1 : -128 : 20 : 0 : 0 : 0 : 0 : 0 : 4 : 0 : 8 : 0 : 1 : 13 : -106 : -39 : 10 : 68 : -104 : 0 : 5 : 0 : 8 : 0 : 1 : 13 : -105 : -39 : 116 : 122 : -118 : -128 : 32 : 0 : 8 : 0 : 1 : 92 : 26 : -36 : 14 : 54 : -88 : -128 : 34 : 0 : 16 : 86 : 111 : 118 : 105 : 100 : 97 : 46 : 111 : 114 : 103 : 32 : 48 : 46 : 57 : 54 : 0 :
How do I extract my public/external port number from the binary data in the stun packet?
Here's how: https://github.com/patmooney/jstun
Run a client (which simply pings the Server and gets back the external IP and port of the request)
./run Test