Received fatal alert: handshake_failure when using Groovy HTTPBuilder for server using TLSv1.2 - api

I have a question regarding the use of HTTPBuilder. While using the snippet below to create issues using the JIRA API, I am receive the error below:
The server where the API is hosted uses TLSv1.2 and that seems to be my problem.
Received fatal alert: handshake_failure
Here are some of my costraints/limitations:
The project runs on Java 7
The version of Grails is 2.4.3
I know that upgrading the version of Java helps. However, I am specifically interested in learning about how changing/rewriting HTTPBuilder will help me in solving this issue.
def http = new HTTPBuilder("https://jira.xxxxxxx.com/rest/api/2/issue")
if(projectKey=='Type1')
{
http.request(POST, JSON) { req ->
headers.'Authorization' = 'Basic xxxxxxxxxxxxxxxxxxxxxxxxxx'
headers.'Content-Type' = 'application/json'
body = [
fields: [
project : [
key: projectKey
],
issuetype : [
name: issueType
],
reporter : [
name: reporter
],
assignee : [
name: assignee
],
customfield_1 : [
value:'Some value1'
],
customfield_2 : [
value:'Some value2'
],
summary : summary,
description: description,
labels : labels
]
]
response.success = { resp, json ->
return json.key
}
Any help will be appreciated!!

Have you tried this:
Usage:
TlsHttpBuilder tlsHttpBuilder = new TlsHttpBuilder(['TLSv1',
'TLSv1.1', 'TLSv1.2'])
class TlsHttpBuilder extends HTTPBuilder {
List sslProtocols
TlsHttpBuilder(List sslProtocols) {
super()
this.sslProtocols = sslProtocols
}
protected HttpClient createClient(HttpParams params) {
def sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, null, new SecureRandom())
def sf = new org.apache.http.conn.ssl.SSLSocketFactory(sslContext) {
protected void prepareSocket(final SSLSocket socket) throws IOException {
if (sslProtocols) {
log.debug("Setting protocols: ${sslProtocols}")
socket.setEnabledProtocols(sslProtocols as String[])
}
}
}
def schemeRegistry = SchemeRegistryFactory.createDefault()
schemeRegistry.register(new org.apache.http.conn.scheme.Scheme("https", sf, 443))
new DefaultHttpClient(new PoolingClientConnectionManager(schemeRegistry), params)
}
}
Reference :
https://gist.github.com/ptaylor/fb5a3abce5c455fbec87f6bfd6386814

Related

Ktor parsing of arrays with nested objects config

I am trying to use the following configuration in Ktor:
source {
quotes {
inputTopicBaseName = "quotes"
providers = [
{
provider = "BHS"
windows = [
{
grace = "PT1M"
size = "PT1M"
}
]
},
{
provider = "LSX"
windows = [
{
grace = "PT1M"
size = "PT1M"
}
]
}
]
}
type = QUOTES
}
When I invoke environment.config.config("source.quotes").configList("providers"), it fails with the following exception
Exception in thread "main" io.ktor.server.config.ApplicationConfigurationException: Property source.quotes.providers.size not found.
at io.ktor.server.config.MapApplicationConfig.configList(MapApplicationConfig.kt:57)
at io.ktor.server.config.MergedApplicationConfig.configList(MergedApplicationConfig.kt:37)
Why is this not working?
This is a bug that will be fixed in Ktor 2.2.0.

Unable to validate the following destination configurations (s3 to SNS)

I am trying to setup an event Notification system on s3 to publish notifications to SNS when a file is being uploaded to s3. Here 's how I implemented it via CDK :
import * as sns from "monocdk/aws-sns";
import * as iam from "monocdk/aws-iam";
import {
GAMMA_ACCOUNT,
PROD_ACCOUNT,
UAT1_ACCOUNT,
UAT2_ACCOUNT,
PERFECT_MILE_ACCOUNT,
} from "../utils/constants/awsAccounts";
import { Construct } from "monocdk";
import * as s3 from "monocdk/aws-s3";
import * as s3n from "monocdk/aws-s3-notifications";
import { CommonResourceStackProps, Stage } from "../stack/CommonResourcesStack";
export class S3NotificationToSNSCustomResource extends Construct {
constructor(
scope: Construct,
id: string,
bucket: s3.IBucket,
stackProps: CommonResourceStackProps
) {
super(scope, id);
const topic = new sns.Topic(this, "Topic", {
displayName: "Sherlock-s3-Event-Notifications-Topic",
topicName: "Sherlock-s3-Event-Notifications-Topic",
});
const topicPolicy = new sns.TopicPolicy(this, "TopicPolicy", {
topics: [topic],
});
const s3ServicePrincipal = new iam.ServicePrincipal("s3.amazonaws.com");
topicPolicy.document.addStatements(
new iam.PolicyStatement({
sid: "0",
actions: ["sns:Publish"],
principals: [s3ServicePrincipal],
resources: [topic.topicArn],
conditions: {
StringEquals: {
"AWS:SourceOwner":
stackProps.stage == Stage.Prod
? PROD_ACCOUNT
: stackProps.stage == Stage.Gamma
? GAMMA_ACCOUNT
: stackProps.stage == Stage.UAT1
? UAT1_ACCOUNT
: UAT2_ACCOUNT,
},
ArnLike: { "AWS:SourceArn": bucket.bucketArn },
},
}),
new iam.PolicyStatement({
sid: "1",
actions: ["sns:Subscribe"],
principals: [new iam.AccountPrincipal(PERFECT_MILE_ACCOUNT)],
resources: [topic.topicArn],
})
);
bucket.addEventNotification(
s3.EventType.OBJECT_CREATED,
new s3n.SnsDestination(topic),
{ prefix: "output/reportingData/openItems/", suffix: "_SUCCESS" }
);
}
}
But, when I try to deploy this, I am getting the following error : An error occurred (InvalidArgument) when calling the PutBucketNotificationConfiguration operation: Unable to validate the following destination configurations
Can anyone help me with it?
I read this post(https://aws.amazon.com/premiumsupport/knowledge-center/unable-validate-destination-s3/) but its resolution is using the templates and I am implementing using the CDK package. Also I have added all the access policies to publish and subscribe.
aws:SourceAccount and aws:SourceOwner are condition keys which are not supported by all services. Amazon S3 notifications use aws:SourceAccount Refer - https://docs.aws.amazon.com/sns/latest/dg/sns-access-policy-use-cases.html#source-account-versus-source-owner

How to get the ressources address of a badge

I'm trying to build an Auction web application based on a scrypto smartcontract.
I have a register function that return a badge, from which I can build proof to call other methods that need authentication.
To build the proof, I need the address of the badge; using the pte-sdk, how would that be possible ?
I use :
const manifestRegistration = new ManifestBuilder()
//call the register function
.callMethod(auction.auctionId, "register", [])
//deposit the resource into my account
.callMethodWithAllResources(accountAddress, "deposit_batch")
.build()
.toString()
const receiptRegistration = await signTransaction(manifestRegistration);
console.log(receiptRegistrationt)
here is receipt :
{
"transactionHash": "b737899a3b78692d2ba49d83ccedeacd66f6168d107a2962828d621d6c73cb37",
"status": "Success",
"outputs": [
"{\"type\":\"Bucket\",\"value\":\"Bucket(1027u32)\"}",
"{\"type\":\"Unit\"}"
],
"logs": [],
"newPackages": [],
"newComponents": [],
"newResources": []
}
How do I know what is the resource in the returned bucket ?
Thank you
The first thing that pops into my head of solving this is returning the address as a string
pub fn register() -> (Bucket, String) -> {
...
(badge, badge.resource_address().to_string())
}
This should pop up in the outputs array

Serializer for type org.janusgraph.graphdb.relations.RelationIdentifier not found

Following error shows up in JanusGraph v0.5.3 server logs while retrieving edges from java client
12277786 [gremlin-server-exec-7] WARN org.apache.tinkerpop.gremlin.server.op.AbstractEvalOpProcessor - The result [[e[ofncw-iyo-4avp-374][24576-hasTag->4144]]] in the request 098dc551-6558-497a-a066-b293edd29833 could not be serialized and returned.
org.apache.tinkerpop.gremlin.driver.ser.SerializationException: java.io.IOException: Serializer for type org.janusgraph.graphdb.relations.RelationIdentifier not found
at org.apache.tinkerpop.gremlin.driver.ser.binary.ResponseMessageSerializer.writeValue(ResponseMessageSerializer.java:86)
at org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1.serializeResponseAsBinary(GraphBinaryMessageSerializerV1.java:143)
at org.apache.tinkerpop.gremlin.server.op.AbstractOpProcessor.makeFrame(AbstractOpProcessor.java:335)
at org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor.handleIterator(TraversalOpProcessor.java:580)
at org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor.lambda$iterateBytecodeTraversal$4(TraversalOpProcessor.java:411)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Serializer for type org.janusgraph.graphdb.relations.RelationIdentifier not found
at org.apache.tinkerpop.gremlin.structure.io.binary.TypeSerializerRegistry.validateInstance(TypeSerializerRegistry.java:392)
at org.apache.tinkerpop.gremlin.structure.io.binary.TypeSerializerRegistry.getSerializer(TypeSerializerRegistry.java:361)
at org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter.write(GraphBinaryWriter.java:90)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.EdgeSerializer.writeValue(EdgeSerializer.java:63)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.EdgeSerializer.writeValue(EdgeSerializer.java:34)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.SimpleTypeSerializer.writeValue(SimpleTypeSerializer.java:91)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.SimpleTypeSerializer.write(SimpleTypeSerializer.java:73)
at org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter.write(GraphBinaryWriter.java:112)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.TraverserSerializer.writeValue(TraverserSerializer.java:49)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.TraverserSerializer.writeValue(TraverserSerializer.java:33)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.SimpleTypeSerializer.writeValue(SimpleTypeSerializer.java:91)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.SimpleTypeSerializer.write(SimpleTypeSerializer.java:73)
at org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter.write(GraphBinaryWriter.java:112)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.CollectionSerializer.writeValue(CollectionSerializer.java:52)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.ListSerializer.writeValue(ListSerializer.java:44)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.ListSerializer.writeValue(ListSerializer.java:29)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.SimpleTypeSerializer.writeValue(SimpleTypeSerializer.java:91)
at org.apache.tinkerpop.gremlin.structure.io.binary.types.SimpleTypeSerializer.write(SimpleTypeSerializer.java:73)
at org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter.write(GraphBinaryWriter.java:112)
at org.apache.tinkerpop.gremlin.driver.ser.binary.ResponseMessageSerializer.writeValue(ResponseMessageSerializer.java:84)
... 10 more
Serializer used in Java client
Map config = new HashMap();
config.put("ioRegistries", Arrays.asList("org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry"));
MessageSerializer serializer = new GraphBinaryMessageSerializerV1();
serializer.configure(config, null);
Cluster.Builder builder = Cluster.build().port(port)
.serializer(serializer).addContactPoints(hosts)
.loadBalancingStrategy(new LoadBalancingStrategy.RoundRobin());
Server side serializers
serializers:
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { serializeResultToString: true }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
# Older serialization versions for backwards compatibility:
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoLiteMessageSerializerV1d0, config: {ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { serializeResultToString: true }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV2d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }}
Why is GraphBinaryMessageSerializerV1 not able to serialize RelationIdentifier even when its ioRegistries are initialized with org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry which registers RelationIdentifier here - https://github.com/JanusGraph/janusgraph/blob/v0.5.3/janusgraph-driver/src/main/java/org/janusgraph/graphdb/tinkerpop/JanusGraphIoRegistry.java#L35
I believe that some of the fixes that allow the IORegistry to hook the GraphBinary serializer have not yet been released although I do see the work on the main JanusGraph branch. [1] I was having the same problem you reported but was able to get things working using the GraphSONMessageSerialializerV3d0 serializer.
[1] https://github.com/JanusGraph/janusgraph/commit/1cb4b6e849e3f9c2802722fe7f84c760cd471429
This setup code works for me:
private Cluster cluster;
private GraphTraversalSource gts;
private DriverRemoteConnection drc;
public GraphTraversalSource createConnection()
{
Map config = new HashMap();
config.put("ioRegistries", Arrays.asList("org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry"));
MessageSerializer serializer = new GraphSONMessageSerializerV3d0();
serializer.configure(config, null);
Cluster.Builder builder = Cluster.build();
builder.addContactPoint("localhost");
builder.port(8182);
builder.enableSsl(false);
builder.serializer(serializer);
this.cluster = builder.create();
this.drc = DriverRemoteConnection.using(cluster);
this.gts = traversal().withRemote(drc);
return(gts);
}
With that configuration I am able to return edges. For example:
public void runTests()
{
GraphTraversalSource g = createConnection();
List<Edge> edge = g.E().limit(1).toList();
System.out.println(edge);
closeConnection();
}
To get this working I disabled the Graph Binary serializer on the Gremlin Server and just left the GraphSON ones in place.

How do I annotate an endpoint in NestJS for OpenAPI that takes Multipart Form Data

My NestJS server has an endpoint that accepts files and also additional form data
For example I pass a file and a user_id of the file creator in the form.
NestJS Swagger needs to be told explicitly that body contains the file and that the endpoint consumes multipart/form-data this is not documented in the NestJS docs https://docs.nestjs.com/openapi/types-and-parameters#types-and-parameters.
Luckily some bugs led to discussion about how to handle this use case
looking at these two discussions
https://github.com/nestjs/swagger/issues/167
https://github.com/nestjs/swagger/issues/417
I was able to put together the following
I have added annotation using a DTO:
the two critical parts are:
in the DTO add
#ApiProperty({
type: 'file',
properties: {
file: {
type: 'string',
format: 'binary',
},
},
})
public readonly file: any;
#IsString()
public readonly user_id: string;
in the controller add
#ApiConsumes('multipart/form-data')
this gets me a working endpoint
and this OpenAPI Json
{
"/users/files":{
"post":{
"operationId":"UsersController_addPrivateFile",
"summary":"...",
"parameters":[
],
"requestBody":{
"required":true,
"content":{
"multipart/form-data":{
"schema":{
"$ref":"#/components/schemas/UploadFileDto"
}
}
}
}
}
}
}
...
{
"UploadFileDto":{
"type":"object",
"properties":{
"file":{
"type":"file",
"properties":{
"file":{
"type":"string",
"format":"binary"
}
},
"description":"...",
"example":"'file': <any-kind-of-binary-file>"
},
"user_id":{
"type":"string",
"description":"...",
"example":"cus_IPqRS333voIGbS"
}
},
"required":[
"file",
"user_id"
]
}
}
Here is what I find a cleaner Approach:
#Injectable()
class FileToBodyInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const ctx = context.switchToHttp();
const req = ctx.getRequest();
if(req.body && req.file?.fieldname) {
const { fieldname } = req.file;
if(!req.body[fieldname]) {
req.body[fieldname] = req.file;
}
}
return next
.handle();
}
}
const ApiFile = (options?: ApiPropertyOptions): PropertyDecorator => (
target: Object, propertyKey: string | symbol
) => {
ApiProperty({
type: 'file',
properties: {
[propertyKey]: {
type: 'string',
format: 'binary',
},
},
})(target, propertyKey);
};
class UserImageDTO {
#ApiFile()
file: Express.Multer.File; // you can name it something else like image or photo
#ApiProperty()
user_id: string;
}
#Controller('users')
export class UsersController {
#ApiBody({ type: UserImageDTO })
// #ApiResponse( { type: ... } ) // some dto to annotate the response
#Post('files')
#ApiConsumes('multipart/form-data')
#UseInterceptors(
FileInterceptor('file'), //this should match the file property name
FileToBodyInterceptor, // this is to inject the file into the body object
)
async addFile(#Body() userImage: UserImageDTO): Promise<void> { // if you return something to the client put it here
console.log({modelImage}); // all the fields and the file
console.log(userImage.file); // the file is here
// ... your logic
}
}
FileToBodyInterceptor and ApiFile are general, I wish they where in the NestJs
You probably need to install #types/multer to have to Express.Multer.File