Provider pactVerify isn't picking up JSON Pact file - gradle

I have two projects in the same repo, with completely separate directory structures (consumer in /test-consumer, provider in /app).
The consumer check outputs a JSON Pact file in /test-consumer/build/pacts, as expected by
dependencies { test { systemProperties['pact.rootDir'] = "$buildDir/pacts" } }
I then copy the file into /app/build/pacts/, and put this same systemProperties line into my provider's build.gradle.
The sample project that I'm plagiarising from is using a Pact broker, so I guessed I can take that out, and replace it with the rootDir, but it's not working. This is what I get:
WARNING: There are no consumers to verify for provider 'Coffee Ordering Provider'
So, it seems like it's finding the Pact files, but can't find a provider+consumer pair in any of them.
TL;DR:
What am I doing wrong?
Here are some code bits to help:
dependencies {
...
test { systemProperties['pact.rootDir'] = "$buildDir/pacts" }
}
pact {
serviceProviders {
'Coffee Ordering Provider' {
port = 8080
startProviderTask = startProvider
terminateProviderTask = stopProvider
stateChangeUrl = url('http://localhost:8080/pactStateChange')
}
}
}

You are getting that warning because you have not told the pact plugin where to find the pact files. For pacts in a directory, add the following:
pact {
serviceProviders {
'Coffee Ordering Provider' {
port = 8080
startProviderTask = startProvider
terminateProviderTask = stopProvider
stateChangeUrl = url('http://localhost:8080/pactStateChange')
hasPactsWith('Coffee Ordering Consumers') {
// Will define a consumer for each pact file in the directory.
// Consumer name is read from contents of pact file
pactFileLocation = file("$buildDir/pacts")
}
}
}
}
Just a note that you were setting the pact.rootDir for all tests, but the pact verification does not run as a test.

Related

Lambda Layers not installing with Serverless

Currently getting the following error with MongoDB:
no saslprep library specified. Passwords will not be sanitized
We are using Webpack so simply installing the module doesn't work (Webpack just ignores it). I found this thread which talks about how to exclude it from Webpack compilations, but then I have to manually load it into every Lambda function which led me to Lambda Layers.
Following the Serverless guide on using Lambda layers allowed me to get my layer published to AWS and included in all of my functions, but for some reason, it doesn't install the modules. If I download the layer using the AWS GUI, I get a folder with just the package.json and package-lock.json files.
My file structure is:
my-project
|_ layers
|_ saslprep
|_ package.json
and my serverless.yml is:
layers:
saslprep:
path: layers/saslprep
compatibleRuntimes:
- nodejs14.x
This is not my preferred solution as I'd like to use 256, but the way I got around this error/warning was by changing the authMechanism from SCRAM-SHA-256 to SCRAM-SHA-1 in the connection string. The serverless-bundle most likely needs to add this dependency into their package to enable support for Mongo 4.0 SHA256 (my best guess!).
You can specify this authentication mechanism by setting the authMechanism parameter to the value SCRAM-SHA-1 in the connection string as shown in the following sample code.
const { MongoClient } = require("mongodb");
// Replace the following with values for your environment.
const username = encodeURIComponent("<username>");
const password = encodeURIComponent("<password>");
const clusterUrl = "<MongoDB cluster url>";
const authMechanism = "SCRAM-SHA-1";
// Replace the following with your MongoDB deployment's connection string.
const uri =
`mongodb+srv://${username}:${password}#${clusterUrl}/?authMechanism=${authMechanism}`;
// Create a new MongoClient
const client = new MongoClient(uri);
// Function to connect to the server
async function run() {
try {
// Connect the client to the server
await client.connect();
// Establish and verify connection
await client.db("admin").command({ ping: 1 });
console.log("Connected successfully to server");
} finally {
// Ensures that the client will close when you finish/error
await client.close();
}
}
run().catch(console.dir);

MassTransit endpoint name is ignored in ConsumerDefinition

The EndpointName property in a ConsumerDefinition file seems to be ignored by MassTransit. I know the ConsumerDefinition is being used because the retry logic works. How do I get different commands to go to a different queue? It seems that I can get them all to go through one central queue but I don't think this is best practice for commands.
Here is my app configuration that executes on startup when creating the MassTransit bus.
Bus.Factory.CreateUsingAzureServiceBus(cfg =>
{
cfg.Host(_config.ServiceBusUri, host => {
host.SharedAccessSignature(s =>
{
s.KeyName = _config.KeyName;
s.SharedAccessKey = _config.SharedAccessKey;
s.TokenTimeToLive = TimeSpan.FromDays(1);
s.TokenScope = TokenScope.Namespace;
});
});
cfg.ReceiveEndpoint("publish", ec =>
{
// this is done to register all consumers in the assembly and to use their definition files
ec.ConfigureConsumers(provider);
});
And my handler definition in the consumer (an azure worker service)
public class CreateAccessPointCommandHandlerDef : ConsumerDefinition<CreateAccessPointCommandHandler>
{
public CreateAccessPointCommandHandlerDef()
{
EndpointName = "specific";
ConcurrentMessageLimit = 4;
}
protected override void ConfigureConsumer(
IReceiveEndpointConfigurator endpointConfigurator,
IConsumerConfigurator<CreateAccessPointCommandHandler> consumerConfigurator
)
{
endpointConfigurator.UseMessageRetry(r =>
{
r.Immediate(2);
});
}
}
In my app that is sending the message I have to configure it to send to the "publish" queue, not "specific".
EndpointConvention.Map<CreateAccessPointsCommand>(new Uri($"queue:specific")); // does not work
EndpointConvention.Map<CreateAccessPointsCommand>(new Uri($"queue:publish")); // this does work
Because you are configuring the receive endpoint yourself, and giving it the name publish, that's the receive endpoint.
To configure the endpoints using the definitions, use:
cfg.ConfigureEndpoints(provider);
This will use the definitions that were registered in the container to configure the receive endpoints, using the consumer endpoint name defined.
This is also explained in the documentation.

How do you define a file response as a Message

I'm using proto to define a REST service
In my service, I'm trying to document that a service responds with a file.
I've looked through here https://github.com/protocolbuffers/protobuf/tree/master/src/google/protobuf but couldn't find anything that looked like a file.
service SomeService {
rpc GetStaticAsset(GetMessageRequest) returns (FileAsset) {
option (google.api.http) = {
get: "/static/{assetName}"
};
}
}
message FileAsset {
¯\_(ツ)_/¯
}
Found the answer here:
message Chunk {
bytes Content = 1;
}

Adding a custom java library using gradle from gitlab with a provisioned deploy token

I got this working with my public github account where I was using something like this:
maven {
url "https://raw.githubusercontent.com/tvelev92/reactnativeandroidmaven/master/"
}
Then I decided I want it to be private and I put it on my company's gitlab and provisioned an access token however, I cannot figure out how to change build.gradle to accomplish a successful import of the pom file. Here is what I have however, I am receiving a 401 server response.
maven {
url "https://gitlabdev../../mobile/mysdk"
credentials(HttpHeaderCredentials) {
name = "password"
value = "..."
}
authentication {
header(HttpHeaderAuthentication)
}
}
please try:
url "https://raw.githubusercontent.com/tvelev92/reactnativeandroidmaven/raw/master/"

FileNotFoundException: `generated/source/apollo/generatedIR/main`

I try to generate my graphql schema using gradle apollo generateApolloClasses. So the first step is to generateMainApolloIR and it is working fine. It is generating a MainAPI.json under
/generated/source/apollo/generatedIR/main/src/main/graphql/client/backend/MainAPI.json. But the generateApolloClasses is failing with:
> java.io.FileNotFoundException: /Users/mctigg/Documents/Repositories/generated/source/apollo/generatedIR/main (Is a directory)
So it is looking into the wrong path! This is my gradle config:
apollo {
nullableValueType = "javaOptional"
outputPackageName = "generated.client.backend"
}
task generateBackendSchemaJson(type: ApolloSchemaIntrospectionTask) {
url = 'src/main/graphql/client/backend/schema.graphqls'
output = 'src/main/graphql/client/backend/schema.json'
}
tasks.findByName('generateMainApolloIR').dependsOn(['generateBackendSchemaJson'])
So how can I configure generateApolloClasses to look into:
/generated/source/apollo/generatedIR/main/src/main/graphql/client/backend/
Instead of
/generated/source/apollo/generatedIR/main/
May be you should set schema file path as follows:
apollo {
schemaFilePath = "/generated/source/apollo/generatedIR/main/src/main/graphql/client/backend/schema.json"
nullableValueType = "javaOptional"
outputPackageName = "generated.client.backend"
}

Resources