Getting Error in simulation "groovy.lang.MissingPropertyException: No such property: ROUTING for class: org.arl.unet.sim.SimulationAgent" - unetstack

I'm using node.startup ={} in the simulation script to generate static routes by sending routeDiscoveryNtf at each node. I've included all headers but still, ROUTING service isn't recognized.
Simulation script is as follows, startup functionality is same for all nodes
//! Simulation: 5-node network
import org.arl.fjage.*
import org.arl.fjage.Agent.*
import org.arl.fjage.RealTimePlatform
import org.arl.unet.sim.*
import org.arl.unet.sim.channels.*
import org.arl.unet.phy.*
import org.arl.unet.phy.Physical.*
import org.arl.unet.net.*
import org.arl.unet.*
import org.arl.unet.DatagramReq
import org.arl.unet.net.Router
import org.arl.unet.Services
platform = RealTimePlatform
channel.model = ProtocolChannelModel
channel.soundSpeed = 1500.mps // c
channel.communicationRange = 100.m // Rc
channel.detectionRange = 100.m // Rd
channel.interferenceRange = 100.m // Ri
channel.pDetection = 1 // pd
channel.pDecoding = 1 // pc
simulate {
def n1 = node '1', address: 1, location: [0.m, 0.m, 0.m], shell: true, stack:"$home/etc/initrc-stack"
n1.startup = {
def router = agentForService ROUTING
router.send new RouteDiscoveryNtf(to:4,nextHop:1)
router.send new RouteDiscoveryNtf(to:2,nextHop:1)
router.send new RouteDiscoveryNtf(to:3,nextHop:1)
router.send new RouteDiscoveryNtf(to:5,nextHop:1)
}
def n2 =node '2', address: 2, location: [70.m, 0.m, 0.m], shell:5102, stack: "$home/etc/initrc-stack"
n2.startup = {
def router = agentForService ROUTING
router.send new RouteDiscoveryNtf(to:4,nextHop:2)
router.send new RouteDiscoveryNtf(to:1,nextHop:2)
router.send new RouteDiscoveryNtf(to:5,nextHop:2)
router.send new RouteDiscoveryNtf(to:3,nextHop:4)
router.send new RouteDiscoveryNtf(to:3,nextHop:1)
router.send new RouteDiscoveryNtf(to:1,nextHop:5)
}
def n3 = node '3', address: 3, location: [-70.m, 0.m, 0.m], shell: 5103, stack:"$home/etc/initrc-stack"
n3.startup = {
def router = agentForService ROUTING
router.send new RouteDiscoveryNtf(to:4,nextHop:3)
router.send new RouteDiscoveryNtf(to:1,nextHop:3)
router.send new RouteDiscoveryNtf(to:5,nextHop:3)
router.send new RouteDiscoveryNtf(to:2,nextHop:4)
router.send new RouteDiscoveryNtf(to:2,nextHop:1)
router.send new RouteDiscoveryNtf(to:2,nextHop:5)
}
def n4 = node '4', address: 4, location: [0.m, 70.m, 0.m], shell: 5104, stack:"$home/etc/initrc-stack"
n4.startup = {
def router = agentForService ROUTING
router.send new RouteDiscoveryNtf(to:1,nextHop:4)
router.send new RouteDiscoveryNtf(to:2,nextHop:4)
router.send new RouteDiscoveryNtf(to:3,nextHop:4)
router.send new RouteDiscoveryNtf(to:5,nextHop:1)
router.send new RouteDiscoveryNtf(to:5,nextHop:2)
router.send new RouteDiscoveryNtf(to:5,nextHop:3)
}
def n5 = node '5', address: 5, location: [0.m, -70.m, 0.m], shell: 5105, stack:"$home/etc/initrc-stack"
n5.startup = {
def router = agentForService ROUTING
router.send new RouteDiscoveryNtf(to: 1 , nextHop:5)
router.send new RouteDiscoveryNtf(to: 3 , nextHop:5)
router.send new RouteDiscoveryNtf(to: 2 , nextHop:5)
router.send new RouteDiscoveryNtf(to: 4 , nextHop:1)
router.send new RouteDiscoveryNtf(to: 4 , nextHop:2)
router.send new RouteDiscoveryNtf(to: 4 , nextHop:3)
}
}
Simulation Error is as follows:
SEVERE: <3> > Exception in agent: simulator
SEVERE: <4> > Exception in agent: simulator
SEVERE: <1> > Exception in agent: simulator
SEVERE: <5> > Exception in agent: simulator
SEVERE: <2> > Exception in agent: simulator
Though stack is being loaded on every node, Routes are not being created.
Log file stats are :
1562654374493|SEVERE|<1>#36:run|Exception in agent: simulator
groovy.lang.MissingPropertyException: No such property: ROUTING for class: org.arl.unet.sim.SimulationAgent
Stack trace: ...
org.arl.unet.sim.SimulationAgent.propertyMissing(initrc.groovy:216) ...
org.arl.unet.sim.SimulationAgent.getProperty(initrc.groovy) ...
ping-sim2$_run_closure1$_closure2.doCall(ping-sim2.groovy:37)
ping-sim2$_run_closure1$_closure2.doCall(ping-sim2.groovy) ...
org.arl.unet.sim.SimulationAgent.this$dist$invoke$2(initrc.groovy)
org.arl.unet.sim.SimulationAgent$1.methodMissing(initrc.groovy) ...
org.arl.unet.sim.SimulationAgent$1.action(initrc.groovy:172)
org.arl.fjage.Agent.run(Agent.java:777) ...

I believe ROUTING service's canonical name is org.arl.unet.Services.ROUTING. So you might have to use that string instead of just ROUTING
def router = agentForService org.arl.unet.Services.ROUTING

Related

Using AWS Lambda functions in Amazon Neptune

I created an AWS Lambda function using this example code in AWS neptuneDB documentation. I followed documentation properly and set the all necessary lambda environmentale variables as well. But when I tested the function it raises an error. Could you please help me solve this issue. I wonder why the code in the AWS neptunedb documentation does not work.
code:
import os, sys, backoff, math
from random import randint
from gremlin_python import statics
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from gremlin_python.driver.protocol import GremlinServerError
from gremlin_python.driver import serializer
from gremlin_python.process.anonymous_traversal import traversal
from gremlin_python.process.graph_traversal import __
from gremlin_python.process.strategies import *
from gremlin_python.process.traversal import T
from tornado.websocket import WebSocketClosedError
from tornado import httpclient
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
from botocore.credentials import ReadOnlyCredentials
from types import SimpleNamespace
reconnectable_err_msgs = [
'ReadOnlyViolationException',
'Server disconnected',
'Connection refused'
]
retriable_err_msgs = ['ConcurrentModificationException'] + reconnectable_err_msgs
network_errors = [WebSocketClosedError, OSError]
retriable_errors = [GremlinServerError] + network_errors
def prepare_iamdb_request(database_url):
service = 'neptune-db'
method = 'GET'
access_key = os.environ['AWS_ACCESS_KEY_ID']
secret_key = os.environ['AWS_SECRET_ACCESS_KEY']
region = os.environ['AWS_REGION']
session_token = os.environ['AWS_SESSION_TOKEN']
creds = SimpleNamespace(
access_key=access_key, secret_key=secret_key, token=session_token, region=region,
)
request = AWSRequest(method=method, url=database_url, data=None)
SigV4Auth(creds, service, region).add_auth(request)
return httpclient.HTTPRequest(database_url, headers=request.headers.items())
def is_retriable_error(e):
is_retriable = False
err_msg = str(e)
if isinstance(e, tuple(network_errors)):
is_retriable = True
else:
is_retriable = any(retriable_err_msg in err_msg for retriable_err_msg in retriable_err_msgs)
print('error: [{}] {}'.format(type(e), err_msg))
print('is_retriable: {}'.format(is_retriable))
return is_retriable
def is_non_retriable_error(e):
return not is_retriable_error(e)
def reset_connection_if_connection_issue(params):
is_reconnectable = False
e = sys.exc_info()[1]
err_msg = str(e)
if isinstance(e, tuple(network_errors)):
is_reconnectable = True
else:
is_reconnectable = any(reconnectable_err_msg in err_msg for reconnectable_err_msg in reconnectable_err_msgs)
print('is_reconnectable: {}'.format(is_reconnectable))
if is_reconnectable:
global conn
global g
conn.close()
conn = create_remote_connection()
g = create_graph_traversal_source(conn)
#backoff.on_exception(backoff.constant,
tuple(retriable_errors),
max_tries=5,
jitter=None,
giveup=is_non_retriable_error,
on_backoff=reset_connection_if_connection_issue,
interval=1)
def query(**kwargs):
id = kwargs['id']
return (g.V(id)
.fold()
.coalesce(
__.unfold(),
__.addV('User').property(T.id, id)
)
.id().next())
def doQuery(event):
return query(id=str(randint(0, 10000)))
def lambda_handler(event, context):
return doQuery(event)
def create_graph_traversal_source(conn):
return traversal().withRemote(conn)
def create_remote_connection():
print('Creating remote connection')
return DriverRemoteConnection(
connection_string(),
'g',
pool_size=1,
message_serializer=serializer.GraphSONSerializersV2d0())
def connection_string():
database_url = 'wss://{}:{}/gremlin'.format(os.environ['neptuneEndpoint'], os.environ['neptunePort'])
if 'USE_IAM' in os.environ and os.environ['USE_IAM'] == 'true':
return prepare_iamdb_request(database_url)
else:
return database_url
conn = create_remote_connection()
g = create_graph_traversal_source(conn)
error message:
{
"errorMessage": "'GraphTraversal' object is not callable",
"errorType": "TypeError",
"requestId": "69e6ecd3-1291-4d21-a8fa-1fc910525fc1",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 111, in lambda_handler\n return doQuery(event)\n",
" File \"/var/task/lambda_function.py\", line 108, in doQuery\n return query(id=str(randint(0, 10000)))\n",
" File \"/var/task/backoff/_sync.py\", line 105, in retry\n ret = target(*args, **kwargs)\n",
" File \"/var/task/lambda_function.py\", line 99, in query\n return (g.V(id)\n"
]
}
log output:
LOGS Name: cloudwatch_lambda_agent State: Subscribed Types: [Platform]
Creating remote connection
EXTENSION Name: cloudwatch_lambda_agent State: Ready Events: [INVOKE,SHUTDOWN]
START RequestId: 69e6ecd3-1291-4d21-a8fa-1fc910525fc1 Version: $LATEST
[ERROR] TypeError: 'GraphTraversal' object is not callable
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 111, in lambda_handler
    return doQuery(event)
  File "/var/task/lambda_function.py", line 108, in doQuery
    return query(id=str(randint(0, 10000)))
  File "/var/task/backoff/_sync.py", line 105, in retry
    ret = target(*args, **kwargs)
  File "/var/task/lambda_function.py", line 99, in query
    return (g.V(id)END RequestId: 69e6ecd3-1291-4d21-a8fa-1fc910525fc1
REPORT RequestId: 69e6ecd3-1291-4d21-a8fa-1fc910525fc1 Duration: 108.64 ms Billed Duration: 109 ms Memory Size: 128 MB Max Memory Used: 88 MB Init Duration: 1025.72 ms

How to use python-socketio with django and reactjs?

I am getting this error when I am using reactjs with django:
Not Found: /socket.io/
HTTP GET /socket.io/?EIO=4&transport=polling&t=NSwqecY 404 [0.02, 127.0.0.1:51874]
wsgi.py ==>file in django project--
import os
from django.core.wsgi import get_wsgi_application
import socketio
from myapp.server import sio
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
django_app = get_wsgi_application()
application = socketio.WSGIApp(sio, django_app)
server.py==> this is file in django project app
async_mode = None
import os
from django.http import HttpResponse
import socketio
basedir = os.path.dirname(os.path.realpath(__file__))
sio = socketio.Server(async_mode=async_mode)
thread = None
global thread
if thread is None:
thread = sio.start_background_task(background_thread)
def background_thread():
"""Example of how to send server generated events to clients."""
count = 0
while True:
sio.sleep(10)
count += 1
sio.emit('my_response', {'data': 'Server generated event'},
namespace='/test'
#sio.event
def close_room(sid, message):
sio.emit('my_response',
{'data': 'Room ' + message['room'] + ' is closing.'},
room=message['room'])
sio.close_room(message['room'])
#sio.event
def connect(sid, environ):
sio.emit('my_response', {'data': 'Connected', 'count': 0}, room=sid)
#sio.event
def disconnect(sid):
print('Client disconnected')
#sio.event
def disconnect(sid):
print('disconnect ', sid)
client.js==>start connection with calling connect function
connect(){
socket = io.connect("http://localhost:8000");
socket.on('connect', function () {
console.log("connected to server")
});}
What should I do?
Or any other library/method recommended.
Thanks in advance..

Finding distance between two nodes using using unetstack with groovy script

I am implementing a routing protocol for underwater communication networks based on the distance between neighboring nodes. I created an agent and written a script to find the distance between neighboring node using a ranging agent but I am getting an error
No such property: ranging for class:.
I will attach scripts I wrote.
3-node-network_test.groovy : It is a simulation script in which I deployed 3 nodes. Node 1 is the sink node, in which ranging agent and sink script will be executed.
Node 2 and 3 are running "ranging agent" and "node_agent".
sink.groovy: Will initialize the beaconing process by broadcasting a beacon.
node_agent: Which receives a beacon from the sink and identify the distance to sink. Here I have written script to find the distance to sink using:
complete script. how to find distance in unetstack?
3-node-network_test.groovy:
//! Simulation: Simple 3-node network
import org.arl.fjage.*
// run the simulation forever
simulate {
node '1', remote: 1101, address: 1, location: [ 0.km, 0.km, -15.m], shell: true, stack: {container ->
container.add 'ranging', new org.arl.unet.phy.Ranging()
container.shell.addInitrc "${script.parent}/sink.groovy"
}
node '2', remote: 1102, address: 2, location: [ 1.km, 0.km, -15.m], shell: 5102, stack: {container ->
container.add 'ranging', new org.arl.unet.phy.Ranging();
//container.shell.addInitrc "${script.parent}/sink.groovy"
container.add 'node_agent', new node_agent();
}
node '3', remote: 1103, address: 3, location: [-1.km, 0.km, -15.m], shell: 5103, stack: { container ->
container.add 'ranging', new org.arl.unet.phy.Ranging()
container.add 'node_agent', new node_agent();
}
}
Sink.groovy:
import org.arl.unet.*
import org.arl.unet.phy.*
import org.arl.unet.mac.*
//import org.arl.unet.nodeinfo.NodeInfo
import org.arl.unet.PDU
import org.arl.fjage.*
import static org.arl.unet.Services.*
import static org.arl.unet.phy.Physical.*
import org.arl.unet.phy.Ranging.*
int hc = 0, ad;
float neighbor_dist;
float rang
subscribe phy;
send = { count = 1 ->
println ''' BROADCASTING '''
count.times {
phy << new DatagramReq(to: Address.BROADCAST, protocol: Protocol.MAC, data: [node.address, hc, 0]);
}
}
node_agent.groovy:
import org.arl.fjage.Message
import org.arl.unet.*
import org.arl.unet.net.Router
import org.arl.unet.phy.*
import org.arl.unet.mac.*
import org.arl.fjage.RealTimePlatform
import org.arl.unet.nodeinfo.NodeInfo
import org.arl.fjage.*
import org.arl.unet.phy.Ranging.*
import org.arl.unet.phy.RangeNtf.*
import org.arl.unet.phy.RangeReq
class node_agent extends UnetAgent {
int neighbor, addr;
float neighbor_distance;
void startup()
{
def phy = agentForService Services.PHYSICAL;
subscribe topic(phy);
def rang = agentForService Services.RANGING;
subscribe topic(rang);
def nodeInfo = agentForService Services.NODE_INFO;
addr = nodeInfo.address;
}
void processMessage(Message msg) {
if (msg instanceof DatagramNtf && msg.protocol == Protocol.MAC)
{
neighbor = msg.from;
println " BEACON RECEIVED FROM:" +neighbor
ranging<< new RangeReq(to: neighbor);
}
else if (msg instanceof RangeNtf )
{
float neighbor_distance = msg.getRange();
println " Distance between node "+addr + " and neighbor" +neighbor+ "is" + neighbor_dis
} // End of if*/
else {
}
} //End of process message
}
The RangeReq needs to be sent to the ranging agent. You can get the agent using agentForService Services.RANGING. Since you're looking it up in the startup() anyway, you can store it in an attribute and use it later to request range. Something like:
def ranging
void startup()
{
:
ranging = agentForService Services.RANGING;
:
}
void processMessage(Message msg)
{
if (msg instanceof DatagramNtf && msg.protocol == Protocol.MAC)
{
neighbor = msg.from;
println " BEACON RECEIVED FROM:" +neighbor
ranging << new RangeReq(to: neighbor);
}
else if (msg instanceof RangeNtf )
{
float neighbor_distance = msg.getRange();
:
}
}
}

how to Add attachment in ICS file

I tried to add attachment in ics file but it not showing in outlook when open it. I am trying to add attachment like when we send meeting request and add attachment in that from outlook, that attachment can view from calendar as well. This is my ics file :
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//appform.com//NONSGML kigkonsult.se iCalcreator 2.18//
METHOD:PUBLISH
X-WR-TIMEZONE:UTC
X-MS-OLK-FORCEINSPECTOROPEN:TRUE
BEGIN:VEVENT
UID:20160719T144014-694839744#appform.com
DTSTAMP:20160719T124014Z
ATTACH;FMTTYPE="application/msword; charset=binary";FILENAME=1468827330fCrj
O.doc:/var/www/html/basearch.appform.com/application/../public/uploads/146
8827330fCrjO.doc
ATTENDEE;RSVP=TRUE;SENT-BY="MAILTO:sajal#mailinator.com";CN=satyendra#hirest
orm.com;DIR="/var/www/html/app/application/../public/uplo
ads/1468827330fCrjO.doc";LANGUAGE=us-EN;X-AGENDA=Interview;X-LENGTH=30 min
:MAILTO:satyendra#mailinator.com
DESCRIPTION:Name: Dean Nestle Jones G\nVacancy: test\nEmployer: Zend\nDate:
Wednesday\, 20thJuly 2016\nTime: 1430 to 1500\n\nSubmit Feedback : http:/
/hirestorm.com/tms/a/Mg==/appid/NDU4/vacid/MTY4/candid/MTY=\n\nCandida
te CV : https://f12b1a775b358d1fc463-637e94f874af614e321f6.ssl.
cf2.rackcdn.com/1468827330fCrjO.doc\nOther Documents : https://f12b1a775
b358d1fc463-637e94f874af614cdn.com/146297361
8PwEwE.jpeg\n
DTSTART:20160720T090000Z
DTEND:20160720T093000Z
LOCATION:1 2 Elmshorn Schleswig-Holstein Germany
SEQUENCE:0
SUMMARY:New Interview Confirmed: Dean Nestle Jones G for test
BEGIN:VALARM
ACTION:PROCEDURE
DESCRIPTION:Name: Dean Nestle Jones G\nVacancy: test\nEmployer: Zend\nDate:
Wednesday\, 20thJuly 2016\nTime: 1430 to 1500\n\nSubmit Feedback : http:/
/hirestorm.com/tms/a/Mg==/appid/NDU4/vacid/MTY4/candid/MTY=\n\nCandida
te CV : https://f12b1a775b358d1fc463-637e94f874af614ce048a5e321d7d0f6.ssl.
cf2.rackcdn.com/1468827330fCrjO.doc\nOther Documents : https://f12b1a775
b358d1fc463-637e94f874af614ce048a5e32cdn.com/146297361
8PwEwE.jpeg\n
TRIGGER:-PT0H15M0S
END:VALARM
END:VEVENT
END:VCALENDAR
Your iCalendar file contains a reference to :
/var/www/html/basearch.appform.com/application/../public/uploads/1468827330fCrjO.doc
This would obviously be something on your machine. You're not embedding any file, you're just pasting a local path. Unless you have Outlook running on linux there's no way it can find that path.
I tried to do it in a simple java
import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
import java.util.HashMap;
import javax.activation.DataHandler;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import com.tba.readProps.Constants;
import com.tba.readProps.ReadProps;
import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.DateTime;
import net.fortuna.ical4j.model.Period;
import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.parameter.Cn;
import net.fortuna.ical4j.model.parameter.Role;
import net.fortuna.ical4j.model.property.Attendee;
import net.fortuna.ical4j.model.property.CalScale;
import net.fortuna.ical4j.model.property.ProdId;
import net.fortuna.ical4j.model.property.Uid;
import net.fortuna.ical4j.model.property.Version;
import net.fortuna.ical4j.util.RandomUidGenerator;
import net.fortuna.ical4j.util.UidGenerator;
public class EmailWithCalendar{
/**
* #param emailAddr
* #param subject
* #param message
*/
public static void sendHtmlEmail(String emailAddr, String subject, String message){
HashMap propertyValues = null;
String smtpHost = "";
try {
propertyValues = ReadProps.initializeProperties();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
smtpHost = (String) propertyValues.get(Constants.SMTP_HOST);
//ManagerPropertiesBean mgrProps = new ManagerPropertiesBean();
//String smtpHost = mgrProps.getMgrProperty("smtpHost");
try {
// start a session with given properties
java.util.Properties props = new java.util.Properties();
props.put("mail.smtp.host", smtpHost);
Session mailSession = Session.getDefaultInstance(props, null);
String fromAddress = null;
fromAddress = (String) propertyValues.get(Constants.FROM_ADDRESS);
if(!"undefined".equals(fromAddress)){
InternetAddress fromAddr = new InternetAddress("test#test.com");
InternetAddress toAddr = new InternetAddress(emailAddr);
MimeMessage myMessage = new MimeMessage(mailSession);
String replyToAddress = null;
replyToAddress = (String) propertyValues.get(Constants.REPLY_ADDRESS);
InternetAddress replyToAddr[] = new InternetAddress[1];
if(!"undefined".equals(replyToAddress))
replyToAddr[0] = new InternetAddress(replyToAddress);
boolean isfromValid = true;
boolean isToValid = true;
boolean emailDomainCheck = true;
MimeBodyPart messageBodyPart =new MimeBodyPart();
messageBodyPart.setContent(message ,"text/html" );
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
myMessage.setContent(multipart);
if(emailDomainCheck==true)
{
myMessage.addRecipient(javax.mail.Message.RecipientType.TO, toAddr);
myMessage.setReplyTo(replyToAddr);
}
else
{
myMessage.setFrom(fromAddr);
myMessage.addRecipient(javax.mail.Message.RecipientType.TO, toAddr);
if(!"undefined".equals(replyToAddress))
myMessage.setReplyTo(replyToAddr);
}
myMessage.setSentDate(new java.util.Date());
myMessage.setSubject(subject);
messageBodyPart.setDataHandler(new DataHandler(
new ByteArrayDataSource(createEvent().toString(), "text/calendar")));// very important
//myMessage.setText(message);
// now send the message!
if(emailDomainCheck==true)
{
if(isfromValid==true && isToValid==true)
{
Transport.send(myMessage);
}
}
else
{
Transport.send(myMessage);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error occurred in ManagerEmailBean.sendHtmlEmail()");
}
}
private static Calendar createEvent() throws ParseException {
// Create the event
String eventName = "Progress Meeting";
//DateTime start = new DateTime(startDate.getTime());
//DateTime end = new DateTime(endDate.getTime());
// Create the date range which is desired.
DateTime start = new DateTime("20100101T070000Z");
DateTime end = new DateTime("20100201T070000Z");;
Period period = new Period(start, end);
VEvent meeting = new VEvent(start, end, eventName);
// add timezone info..
//meeting.getProperties().add(tz.getTimeZoneId());
// generate unique identifier..
UidGenerator ug = new RandomUidGenerator();
Uid uid = ug.generateUid();
meeting.getProperties().add(uid);
// add attendees..
Attendee dev1 = new Attendee(URI.create("mailto:dev1#test.com"));
dev1.getParameters().add(Role.REQ_PARTICIPANT);
dev1.getParameters().add(new Cn("Developer 1"));
meeting.getProperties().add(dev1);
Attendee dev2 = new Attendee(URI.create("mailto:dev2#test.com"));
dev2.getParameters().add(Role.OPT_PARTICIPANT);
dev2.getParameters().add(new Cn("Developer 2"));
meeting.getProperties().add(dev2);
// Create a calendar
net.fortuna.ical4j.model.Calendar icsCalendar = new net.fortuna.ical4j.model.Calendar();
icsCalendar.getProperties().add(new ProdId("-//Events Calendar//iCal4j 1.0//EN"));
icsCalendar.getProperties().add(Version.VERSION_2_0);
icsCalendar.getProperties().add(CalScale.GREGORIAN);
// Add the event and print
icsCalendar.getComponents().add(meeting);
System.out.println(icsCalendar);
return icsCalendar;
}
public static void main(String[] args) {
sendHtmlEmail("dev.test#gmail.com", "Test", "sjgsfgsf<p>dshdfsdf</p>");
}
}

Generating X509Certificate using bouncycastle X509v3CertificateBuilder

I'm attempting to port JXTA to run on App Engine. Given that the BouncyCastle "BC" provider is not yet supported on App Engine, I have to port the existing JXTA code to generate a X509Certificate using white-listed classes. My knowledge of Crypto is minimal and i'm not certain that what i'm trying to accomplish is even possible. Here is the original code from PSEUtils.java from the JXTA project:
PSEUtils.java
There's a helper class which contains the java.security.cert.X509Certificate:
public static class IssuerInfo {
public X509Certificate cert; // subject Cert
public PrivateKey subjectPkey; // subject private key
public X509Certificate issuer; // issuer Cert
public PrivateKey issuerPkey; // issuer private key
}
In the method:
public static IssuerInfo genCert(X500Principal subject, KeyPair keypair, IssuerInfo issuerinfo)
I'm passing in subject as:
new X500Principal("CN="+useCN)
keypair as (from original code):
KeyPairGenerator g = KeyPairGenerator.getInstance("RSA");
g.initialize(1024, UTILS.srng);
KeyPair keypair = g.generateKeyPair();
and the jxta coded IssuerInfo.
Now since I can't pull in the bouncycastle.jce packages, I've had to remove the X509Principal and X509V3CertificateGenerator code that JXTA uses and attempt to replace it with an implementation that complies with the GAE restrictions. Here is what I currently have for the genCert method using org.bouncycastle.X509.X509v3CertificateBuilder.
SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(keypair.getPublic().getEncoded());
X509v3CertificateBuilder v3CertGen = new X509v3CertificateBuilder(
new X500Name(issuer.getName()),
BigInteger.ONE,
today, until,
new X500Name(subject.getName()),
subPubKeyInfo);
The problem is that I can't get keypair.getPublic().getEncoded() to work with the SubjectPublicKeyInfo.getInstance() method. Throws java.lang.IllegalArgumentException: unknown object in factory: [B
Public Key appears to be populated upon inspection:
Sun RSA public key, 1024 bits
modulus: 117521430893506212334140912845641570591161279468597426442875306202350445904550279678434051874985419676760802566018092318362676224355315431299979507080364677679613392086245588766565617009250512996843008784370448997729071786062596049780632058501646041736216482596596901215941577208285499619376322050871534546271
public exponent: 65537
I've found the following SO link which demonstrates this code working:
Sign CSR using Bouncy Castle
My attempt to convert genCert is below but for some reason, I can't get past creating SubjectPublicKeyInfo from the encoded public key?
Any help is greatly appreciated.
public static IssuerInfo genCert(X500Principal subject, KeyPair keypair, IssuerInfo issuerinfo) {
IssuerInfo info = new IssuerInfo();
try {
// set up issuer
PrivateKey signer;
X500Principal issuer;
if (null == issuerinfo) { // self-signed root cert
signer = keypair.getPrivate();
issuer = new X500Principal(subject.getEncoded());
} else { // issuer signed service sert
signer = issuerinfo.subjectPkey;
X500Principal issuer_subject = issuerinfo.cert.getSubjectX500Principal();
issuer = new X500Principal(issuer_subject.getEncoded());
}
// set validity 10 years from today
Date today = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(today);
cal.add(Calendar.YEAR, 10);
Date until = cal.getTime();
SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(keypair.getPublic().getEncoded());
//**Can't get here so i'm not sure if the rest of this works?**
AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA");
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
RSAPrivateCrtKeyParameters cps = (RSAPrivateCrtKeyParameters) keypair.getPrivate();
ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(cps);
X509CertificateHolder certHolder = v3CertGen.build(sigGen);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// Read user Certificate
InputStream is1 = new ByteArrayInputStream(certHolder.getEncoded());
X509Certificate eeCert = (X509Certificate) cf.generateCertificate(is1);
is1.close();
I was able to accomplish this with help from Rene Mayrhofer's code.
I've provided my implementation which has only be tested in a local testing environment but it appears to work:
package net.jxta.impl.membership.pse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.Logger;
import javax.security.auth.x500.X500Principal;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERBMPString;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERInteger;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DEROutputStream;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.DigestInfo;
import org.bouncycastle.asn1.x509.RSAPublicKeyStructure;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.TBSCertificateStructure;
import org.bouncycastle.asn1.x509.Time;
import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
import org.bouncycastle.asn1.x509.X509CertificateStructure;
import org.bouncycastle.asn1.x509.X509Name;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.encodings.PKCS1Encoding;
import org.bouncycastle.crypto.engines.RSAEngine;
import org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
import org.bouncycastle.jce.PrincipalUtil;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.jce.provider.X509CertificateObject;
import org.bouncycastle.x509.X509Util;
import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
/** This class uses the Bouncycastle lightweight API to generate X.509 certificates programmatically.
* It assumes a CA certificate and its private key to be available and can sign the new certificate with
* this CA. Some of the code for this class was taken from
* org.bouncycastle.x509.X509V3CertificateGenerator, but adapted to work with the lightweight API instead of
* JCE (which is usually not available on MIDP2.0).
*
* #author Rene Mayrhofer
*/
public class X509CertificateGenerator {
/** Our log4j logger. */
private static Logger logger = Logger.getLogger(X509CertificateGenerator.class.getName());
/** This holds the certificate of the CA used to sign the new certificate. The object is created in the constructor. */
private X509Certificate caCert;
/** This holds the private key of the CA used to sign the new certificate. The object is created in the constructor. */
private RSAPrivateCrtKeyParameters caPrivateKey;
private boolean useBCAPI;
private boolean useCACert;
public X509CertificateGenerator(String caFile, String caPassword, String caAlias, boolean useBCAPI)
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, InvalidKeyException, NoSuchProviderException, SignatureException {
this.useBCAPI = useBCAPI;
this.useCACert = true;
logger.info("Loading CA certificate and private key from file '" + caFile + "', using alias '" + caAlias + "' with "
+ (this.useBCAPI ? "Bouncycastle lightweight API" : "JCE API"));
KeyStore caKs = KeyStore.getInstance("PKCS12");
caKs.load(new FileInputStream(new File(caFile)), caPassword.toCharArray());
// load the key entry from the keystore
Key key = caKs.getKey(caAlias, caPassword.toCharArray());
if (key == null) {
throw new RuntimeException("Got null key from keystore!");
}
RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) key;
caPrivateKey = new RSAPrivateCrtKeyParameters(privKey.getModulus(), privKey.getPublicExponent(), privKey.getPrivateExponent(),
privKey.getPrimeP(), privKey.getPrimeQ(), privKey.getPrimeExponentP(), privKey.getPrimeExponentQ(), privKey.getCrtCoefficient());
// and get the certificate
caCert = (X509Certificate) caKs.getCertificate(caAlias);
if (caCert == null) {
throw new RuntimeException("Got null cert from keystore!");
}
logger.info("Successfully loaded CA key and certificate. CA DN is '" + caCert.getSubjectDN().getName() + "'");
caCert.verify(caCert.getPublicKey());
logger.info("Successfully verified CA certificate with its own public key.");
}
public X509CertificateGenerator(boolean useBCAPI) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, InvalidKeyException, NoSuchProviderException, SignatureException {
this.useBCAPI = useBCAPI;
this.useCACert = false;
}
public X509Certificate createCertificate(String dn, int validityDays, X500Principal issuer, KeyPair keypairca) throws
IOException, InvalidKeyException, SecurityException, SignatureException, NoSuchAlgorithmException, DataLengthException, CryptoException, KeyStoreException, NoSuchProviderException, CertificateException, InvalidKeySpecException {
logger.info("Generating certificate for distinguished subject name '" +
dn + "', valid for " + validityDays + " days");
RSAPrivateCrtKey pK = (RSAPrivateCrtKey) keypairca.getPrivate();
caPrivateKey = new RSAPrivateCrtKeyParameters(pK.getModulus(), pK.getPublicExponent(), pK.getPrivateExponent(),
pK.getPrimeP(), pK.getPrimeQ(), pK.getPrimeExponentP(), pK.getPrimeExponentQ(), pK.getCrtCoefficient());
SecureRandom sr = new SecureRandom();
PublicKey pubKey;
PrivateKey privKey;
logger.info("Creating RSA keypair");
// generate the keypair for the new certificate
if (useBCAPI) {
RSAKeyPairGenerator gen = new RSAKeyPairGenerator();
gen.init(new RSAKeyGenerationParameters(BigInteger.valueOf(3), sr, 1024, 80));
AsymmetricCipherKeyPair keypair = gen.generateKeyPair();
logger.info("Generated keypair, extracting components and creating public structure for certificate");
RSAKeyParameters publicKey = (RSAKeyParameters) keypair.getPublic();
RSAPrivateCrtKeyParameters privateKey = (RSAPrivateCrtKeyParameters) keypair.getPrivate();
// used to get proper encoding for the certificate
RSAPublicKeyStructure pkStruct = new RSAPublicKeyStructure(publicKey.getModulus(), publicKey.getExponent());
logger.info("New public key is '" + new String(Hex.encodeHex(pkStruct.getEncoded())) +
", exponent=" + publicKey.getExponent() + ", modulus=" + publicKey.getModulus());
// JCE format needed for the certificate - because getEncoded() is necessary...
pubKey = KeyFactory.getInstance("RSA").generatePublic(
new RSAPublicKeySpec(publicKey.getModulus(), publicKey.getExponent()));
// and this one for the KeyStore
privKey = KeyFactory.getInstance("RSA").generatePrivate(
new RSAPrivateCrtKeySpec(publicKey.getModulus(), publicKey.getExponent(),
privateKey.getExponent(), privateKey.getP(), privateKey.getQ(),
privateKey.getDP(), privateKey.getDQ(), privateKey.getQInv()));
}
else {
// this is the JSSE way of key generation
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024, sr);
KeyPair keypair = keyGen.generateKeyPair();
privKey = keypair.getPrivate();
pubKey = keypair.getPublic();
}
Calendar expiry = Calendar.getInstance();
expiry.add(Calendar.DAY_OF_YEAR, validityDays);
X509Name x509Name = new X509Name("CN=" + dn);
X509Name x509Issuer = new X509Name(issuer.getName());
V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator();
certGen.setSerialNumber(new DERInteger(BigInteger.valueOf(System.currentTimeMillis())));
certGen.setIssuer(x509Issuer);//issuer.getName());//PrincipalUtil.getSubjectX509Principal(caCert));
certGen.setSubject(x509Name);
DERObjectIdentifier sigOID = X509Util.getAlgorithmOID("SHA1WithRSAEncryption");
AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(sigOID, new DERNull());
certGen.setSignature(sigAlgId);
certGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(
new ByteArrayInputStream(pubKey.getEncoded())).readObject()));
certGen.setStartDate(new Time(new Date(System.currentTimeMillis())));
certGen.setEndDate(new Time(expiry.getTime()));
logger.info("Certificate structure generated, creating SHA1 digest");
// attention: hard coded to be SHA1+RSA!
SHA1Digest digester = new SHA1Digest();
AsymmetricBlockCipher rsa = new PKCS1Encoding(new RSAEngine());
TBSCertificateStructure tbsCert = certGen.generateTBSCertificate();
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DEROutputStream dOut = new DEROutputStream(bOut);
dOut.writeObject(tbsCert);
// and now sign
byte[] signature;
if (useBCAPI) {
byte[] certBlock = bOut.toByteArray();
// first create digest
logger.info("Block to sign is '" + new String(Hex.encodeHex(certBlock)) + "'");
digester.update(certBlock, 0, certBlock.length);
byte[] hash = new byte[digester.getDigestSize()];
digester.doFinal(hash, 0);
// and sign that
rsa.init(true, caPrivateKey);
DigestInfo dInfo = new DigestInfo( new AlgorithmIdentifier(X509ObjectIdentifiers.id_SHA1, null), hash);
byte[] digest = dInfo.getEncoded(ASN1Encodable.DER);
signature = rsa.processBlock(digest, 0, digest.length);
}
else {
// or the JCE way
PrivateKey caPrivKey = KeyFactory.getInstance("RSA").generatePrivate(
new RSAPrivateCrtKeySpec(caPrivateKey.getModulus(), caPrivateKey.getPublicExponent(),
caPrivateKey.getExponent(), caPrivateKey.getP(), caPrivateKey.getQ(),
caPrivateKey.getDP(), caPrivateKey.getDQ(), caPrivateKey.getQInv()));
Signature sig = Signature.getInstance(sigOID.getId());
sig.initSign(caPrivKey, sr);
sig.update(bOut.toByteArray());
signature = sig.sign();
}
logger.info("SHA1/RSA signature of digest is '" + new String(Hex.encodeHex(signature)) + "'");
// and finally construct the certificate structure
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(tbsCert);
v.add(sigAlgId);
v.add(new DERBitString(signature));
X509CertificateObject clientCert = new X509CertificateObject(new X509CertificateStructure(new DERSequence(v)));
logger.info("Verifying certificate for correct signature with CA public key");
if(useCACert) clientCert.verify(caCert.getPublicKey());
return clientCert;
}
}

Resources