Index migration failed - amazon-web-services

I'm working with docker and 1.1.0 opendistro for es version, i noticed that if i put on kibana.yml
`opendistro_security.multitenancy.enabled: true`
i get this error:
index migration failed for opendistro 7.1.1
i checked migrate_tenants.js:
/*
* Copyright 2015-2018 _floragunn_ GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* Portions Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
import _ from 'lodash';
import Boom from 'boom';
import elasticsearch from 'elasticsearch';
import wrapElasticsearchError from './../backend/errors/wrap_elasticsearch_error';
import { KibanaMigrator} from "../../../../src/legacy/server/saved_objects/migrations/kibana";
async function migrateTenants (server) {
const backend = server.plugins.opendistro_security.getSecurityBackend();
try {
let tenantInfo = await backend.getTenantInfoWithInternalUser();
if (tenantInfo) {
let indexNames = Object.keys(tenantInfo);
for (var index = 0; index < indexNames.length; ++index) {
await migrateTenantIndex(indexNames[index], server);
}
}
} catch (error) {
server.log(['error', 'migration'], error);
throw error;
}
}
async function migrateTenantIndex(tenantIndexName, server) {
const {kbnServer} = mockKbnServer(server.kibanaMigrator.kbnServer, server, tenantIndexName);
const migrator = new KibanaMigrator({kbnServer});
await migrator.awaitMigration();
}
async function migrateTenant(tenantIndexName, force, server) {
const backend = server.plugins.opendistro_security.getSecurityBackend();
try {
let tenantInfo = await backend.getTenantInfoWithInternalUser();
if (tenantInfo) {
if (tenantInfo[tenantIndexName] || (force == true)) {
await migrateTenantIndex(tenantIndexName, server);
return {statusCode:200, message: tenantIndexName + " migrated."}
} else {
return Boom.badRequest('Index ' + tenantIndexName + ' not found or not a tenand index. Force migration: ' + force);
}
} else {
return Boom.badImplementation("Could not fetch tenant info.");
}
} catch (error) {
server.log(['error', 'migration'], error);
return wrapElasticsearchError(error);
}
}
function mockKbnServer(originalKbnServer, server, indexname) {
const kbnServer = {
version: originalKbnServer.version,
ready: originalKbnServer.ready,
uiExports: originalKbnServer.uiExports,
server: {
config: () => ({
get: ((name) => {
switch (name) {
case 'kibana.index':
return indexname;
case 'migrations.batchSize':
return originalKbnServer.server.config().get("migrations.batchSize");
case 'migrations.pollInterval':
return originalKbnServer.server.config().get("migrations.pollInterval");
case 'migrations.scrollDuration':
return originalKbnServer.server.config().get("migrations.scrollDuration");
default:
throw new Error(`Unexpected config ${name}`);
}
})
}),
log: function (tags, data, timestamp, _internal) {
server.log(tags, data, timestamp, _internal);
},
plugins: originalKbnServer.server.plugins
}
};
return { kbnServer };
}
module.exports.migrateTenants=migrateTenants;
module.exports.migrateTenant=migrateTenant;
kibana returns this error in logs:
kibana | {"type":"log","#timestamp":"2019-08-06T09:36:33Z","tags":["status","plugin:opendistro_security#7.1.1","info"],"pid":1,"state":"yellow","message":"Status changed from yellow to yellow - Tenant indices migration failed","prevState":"yellow","prevMsg":"Setting up index template."}
kibana | {"type":"log","#timestamp":"2019-08-06T09:36:34Z","tags":["info","migrations"],"pid":1,"message":"Creating index .kibana_1."}
kibana | {"type":"log","#timestamp":"2019-08-06T09:36:34Z","tags":["info","migrations"],"pid":1,"message":"Pointing alias .kibana to .kibana_1."}
if i disable multitenancy by putting opendistro_security.multitenancy.enabled: false, when i try to login with users that are not admin i get this error:
`elasticsearch | [2019-08-06T09:24:30,239][WARN ][c.a.o.s.c.PrivilegesInterceptorImpl] [a5790f362956] Tenant global_tenant is not allowed for user cn=user,ou=people,dc=example,dc=com`
How can i fix this?

Related

Google Workspace: Add all users in a child organization unit to a group using Google Apps Script

I'd like to add all users in a child Organization Unit to a group. I can do that in Admin Dashboard but it only shows 50 users at a time. Since we have thousands of users in each child OU, this process would be inconvenience.
My solution:
I followed a guide (Source) and used Google Apps Script to run the following code but it simply didn't do anything. The log shows "Execution started" then "Execution completed" but no user is moved to the group. I suspect the format for the OU in the code is wrong. It is a bit tricky to get it right especially the OU is Arabic (Right to Left). Any idea what could be wrong?
function myFunction() {
/**
* Add all users of an organizational unit (OU) to specific groups
* in Google Workspace
*
* Usage:
* Change the OU variable, in a format of /OU/SubOU/SubSubOU. The root OU is represented as /
* Change the groupEmails variable, which is a list of group emails.
*
* © 2021 xFanatical, Inc.
* #license MIT
*
* #since 1.0.0 proof of concept
*/
const OU = '/كلية الطب/الطلبة/طلبة الدراسات الاولية 2019 - 2020/testing'
const groupEmails = ['100gb.limit#uokufa.edu.iq']
function addAllOUUsersToGroup() {
let pageToken
let page
do {
page = AdminDirectory.Users.list({
customer: 'my_customer',
maxResults: 100,
pageToken,
query: `orgUnitPath='${OU}'`,
})
let users = page.users
if (users) {
users.forEach((user) => {
groupEmails.forEach((groupEmail) => {
try {
AdminDirectory.Members.insert({
email: user.primaryEmail,
role: 'MEMBER',
type: 'USER',
}, groupEmail)
Logger.log(`Added user [${user.primaryEmail}] to group [${groupEmail}]`)
} catch (e) {
Logger.log(`Failed to add user [${user.primaryEmail}] to group [${groupEmail}], error: ${e.details && e.details.message && e.details.message}`)
}
})
})
} else {
Logger.log('No users found.')
}
pageToken = page.nextPageToken
} while (pageToken)
}
}
Issue:
You are not executing the function addAllOUUsersToGroup.
addAllOUUsersToGroup is declared inside myFunction, but it is never called. Therefore, if you execute myFunction, addAllOUUsersToGroup won't run.
Solution:
Either call addAllOUUsersToGroup inside myFunction. For example:
function myFunction() {
// ...stuff...
function addAllOUUsersToGroup() {
// ...stuff...
}
addAllOUUsersToGroup(); // <== ADD THIS
}
Or, alternatively, take the function addAllOUUsersToGroup outside myFunction and call it directly:
function addAllOUUsersToGroup() { <== THIS IS NOT INSIDE myFunction
// ...stuff...
}
Reference:
Calling functions

Put event in Amazaon Event bus using Jmeter

We are introducing an event bridge to communicate btw 2 components and we want to Performance test the inbound event bus.
We are using jmeter and want to to do a put event in this inbound event bus. has anyone done something like this ?
Probably the most straightforward way is using AWS SDK for Java from JSR223 Test Elements with Groovy
Example code can be found at Working with Amazon EventBridge, I'll add it here just in case
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package com.example.eventbridge;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.eventbridge.EventBridgeClient;
import software.amazon.awssdk.services.eventbridge.model.EventBridgeException;
import software.amazon.awssdk.services.eventbridge.model.PutEventsRequest;
import software.amazon.awssdk.services.eventbridge.model.PutEventsRequestEntry;
import software.amazon.awssdk.services.eventbridge.model.PutEventsResponse;
import software.amazon.awssdk.services.eventbridge.model.PutEventsResultEntry;
import java.util.ArrayList;
import java.util.List;
/**
* To run this Java V2 code example, ensure that you have setup your development environment, including your credentials.
*
* For information, see this documentation topic:
*
* https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
*/
public class PutEvents {
public static void main(String[] args) {
final String USAGE =
"To run this example, supply two resources, identified by Amazon Resource Name (ARN), which the event primarily concerns. " +
"Any number, including zero, may be present. \n" +
"For example: PutEvents <resourceArn> <resourceArn2>\n";
if (args.length != 2) {
System.out.println(USAGE);
System.exit(1);
}
String resourceArn = args[0];
String resourceArn2 = args[1];
Region region = Region.US_WEST_2;
EventBridgeClient eventBrClient = EventBridgeClient.builder()
.region(region)
.build();
putEBEvents(eventBrClient, resourceArn, resourceArn2);
eventBrClient.close();
}
public static void putEBEvents(EventBridgeClient eventBrClient, String resourceArn, String resourceArn2 ) {
try {
// Populate a List with the resource ARN values
List<String> resources = new ArrayList<String>();
resources.add(resourceArn);
resources.add(resourceArn2);
PutEventsRequestEntry reqEntry = PutEventsRequestEntry.builder()
.resources(resources)
.source("com.mycompany.myapp")
.detailType("myDetailType")
.detail("{ \"key1\": \"value1\", \"key2\": \"value2\" }")
.build();
// Add the PutEventsRequestEntry to a list
List<PutEventsRequestEntry> list = new ArrayList<PutEventsRequestEntry>();
list.add(reqEntry);
PutEventsRequest eventsRequest = PutEventsRequest.builder()
.entries(reqEntry)
.build();
PutEventsResponse result = eventBrClient.putEvents(eventsRequest);
for (PutEventsResultEntry resultEntry : result.entries()) {
if (resultEntry.eventId() != null) {
System.out.println("Event Id: " + resultEntry.eventId());
} else {
System.out.println("Injection failed with Error Code: " + resultEntry.errorCode());
}
}
} catch (EventBridgeException e) {
System.err.println(e.awsErrorDetails().errorMessage());
System.exit(1);
}
}
}
Was able to do it by using the os process sampler and using the AWS cli commands.

How to test endorsement policy for the business network in multiple organizations

I have following this tutorial to setup multiple organizations. According to step 13 before committing transaction requires both organizations should sign off. How can I test that both organizations are endorsing transaction?
Give the proposal responses you are receiving from endorsing peer you can iterate to check validity of the signatures. Here for example code from Java SDK which handles this:
/*
* Verifies that a Proposal response is properly signed. The payload is the
* concatenation of the response payload byte string and the endorsement The
* certificate (public key) is gotten from the Endorsement.Endorser.IdBytes
* field
*
* #param crypto the CryptoPrimitives instance to be used for signing and
* verification
*
* #return true/false depending on result of signature verification
*/
public boolean verify(CryptoSuite crypto) {
if (isVerified()) { // check if this proposalResponse was already verified by client code
return isVerified();
}
if (isInvalid()) {
this.isVerified = false;
}
FabricProposalResponse.Endorsement endorsement = this.proposalResponse.getEndorsement();
ByteString sig = endorsement.getSignature();
try {
Identities.SerializedIdentity endorser = Identities.SerializedIdentity
.parseFrom(endorsement.getEndorser());
ByteString plainText = proposalResponse.getPayload().concat(endorsement.getEndorser());
if (config.extraLogLevel(10)) {
if (null != diagnosticFileDumper) {
StringBuilder sb = new StringBuilder(10000);
sb.append("payload TransactionBuilderbytes in hex: " + DatatypeConverter.printHexBinary(proposalResponse.getPayload().toByteArray()));
sb.append("\n");
sb.append("endorser bytes in hex: "
+ DatatypeConverter.printHexBinary(endorsement.getEndorser().toByteArray()));
sb.append("\n");
sb.append("plainText bytes in hex: " + DatatypeConverter.printHexBinary(plainText.toByteArray()));
logger.trace("payload TransactionBuilderbytes: " +
diagnosticFileDumper.createDiagnosticFile(sb.toString()));
}
}
this.isVerified = crypto.verify(endorser.getIdBytes().toByteArray(), config.getSignatureAlgorithm(),
sig.toByteArray(), plainText.toByteArray()
);
} catch (InvalidProtocolBufferException | CryptoException e) {
logger.error("verify: Cannot retrieve peer identity from ProposalResponse. Error is: " + e.getMessage(), e);
this.isVerified = false;
}
return this.isVerified;
} // verify
Of course you can achive same results with other SDK in pretty similar way.

How to unit test grpc-java server implementation functions?

I have an implementation of GRPC-java server code, but I didn't find the example code to unit test the StreamObserver. Does anyone know the right way to unit test the function?
public class RpcTrackDataServiceImpl implements TrackDataServiceGrpc.TrackDataService {
#Override
public void getTracks(GetTracksRequest request, StreamObserver < GetTracksResponse > responseObserver) {
GetTracksResponse reply = GetTracksResponse
.newBuilder()
.addTracks(TrackInfo.newBuilder()
.setOwner("test")
.setTrackName("test")
.build())
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
Unit testing is very straight forward using the InProcess transport mentioned by Eric above. Here is an example a bit more explicit on code:
We test a service based on this protobuff definition:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "servers.dummy";
option java_outer_classname = "DummyProto";
option objc_class_prefix = "DMYS";
package dummy;
import "general.proto";
// The dummy service definition.
service DummyService {
// # Misc
// Returns the server version
rpc getVersion (Empty) returns (ServerVersion) {}
// Returns the java version
rpc getJava (Empty) returns (JavaVersion) {}
}
// Transmission data types
(The following file is included above:)
syntax = "proto3";
option java_multiple_files = true;
option java_package = "general";
option java_outer_classname = "General";
option objc_class_prefix = "G";
// Transmission data types
message Empty {} // Empty Request or Reply
message ServerVersion {
string version = 1;
}
message JavaVersion {
string version = 1;
}
The DummyService based on the generated Java from the Protoc compiler is the following:
package servers.dummy;
import java.util.logging.Logger;
import general.Empty;
import general.JavaVersion;
import general.ServerVersion;
import io.grpc.stub.StreamObserver;
public class DummyService extends DummyServiceGrpc.DummyServiceImplBase {
private static final Logger logger = Logger.getLogger(DummyService.class.getName());
#Override
public void getVersion(Empty req, StreamObserver<ServerVersion> responseObserver) {
logger.info("Server Version-Request received...");
ServerVersion version = ServerVersion.newBuilder().setVersion("1.0.0").build();
responseObserver.onNext(version);
responseObserver.onCompleted();
}
#Override
public void getJava(Empty req, StreamObserver<JavaVersion> responseObserver) {
logger.info("Java Version Request received...");
JavaVersion version = JavaVersion.newBuilder().setVersion(Runtime.class.getPackage().getImplementationVersion() + " (" + Runtime.class.getPackage().getImplementationVendor() + ")").build();
responseObserver.onNext(version);
responseObserver.onCompleted();
}
}
Now we build an InProcessServer that runs our Dummy service (or any other service you want to test):
package servers;
import io.grpc.Server;
import io.grpc.inprocess.InProcessServerBuilder;
import java.io.IOException;
import java.util.logging.Logger;
import servers.util.PortServer;
/**
* InProcessServer that manages startup/shutdown of a service within the same process as the client is running. Used for unit testing purposes.
* #author be
*/
public class InProcessServer<T extends io.grpc.BindableService> {
private static final Logger logger = Logger.getLogger(PortServer.class.getName());
private Server server;
private Class<T> clazz;
public InProcessServer(Class<T> clazz){
this.clazz = clazz;
}
public void start() throws IOException, InstantiationException, IllegalAccessException {
server = InProcessServerBuilder
.forName("test")
.directExecutor()
.addService(clazz.newInstance())
.build()
.start();
logger.info("InProcessServer started.");
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
// Use stderr here since the logger may have been reset by its JVM shutdown hook.
System.err.println("*** shutting down gRPC server since JVM is shutting down");
InProcessServer.this.stop();
System.err.println("*** server shut down");
}
});
}
void stop() {
if (server != null) {
server.shutdown();
}
}
/**
* Await termination on the main thread since the grpc library uses daemon threads.
*/
public void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
}
We can now test the service using the following unit test:
package servers;
import static org.junit.Assert.*;
import general.ServerVersion;
import io.grpc.ManagedChannel;
import io.grpc.StatusRuntimeException;
import io.grpc.inprocess.InProcessChannelBuilder;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import servers.dummy.DummyService;
import servers.dummy.DummyServiceGrpc;
import servers.dummy.DummyServiceGrpc.DummyServiceBlockingStub;
import servers.dummy.DummyServiceGrpc.DummyServiceStub;
public class InProcessServerTest {
private static final Logger logger = Logger.getLogger(InProcessServerTest.class.getName());
private InProcessServer<DummyService> inprocessServer;
private ManagedChannel channel;
private DummyServiceBlockingStub blockingStub;
private DummyServiceStub asyncStub;
public InProcessServerTest() {
super();
}
#Test
public void testInProcessServer() throws InterruptedException{
try {
String version = getServerVersion();
assertEquals("1.0.0", version);
} finally {
shutdown();
}
}
/** Ask for the server version */
public String getServerVersion() {
logger.info("Will try to get server version...");
ServerVersion response;
try {
response = blockingStub.getVersion(null);
} catch (StatusRuntimeException e) {
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
fail();
return "";
}
return response.getVersion();
}
#Before
public void beforeEachTest() throws InstantiationException, IllegalAccessException, IOException {
inprocessServer = new InProcessServer<DummyService>(DummyService.class);
inprocessServer.start();
channel = InProcessChannelBuilder
.forName("test")
.directExecutor()
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
// needing certificates.
.usePlaintext(true)
.build();
blockingStub = DummyServiceGrpc.newBlockingStub(channel);
asyncStub = DummyServiceGrpc.newStub(channel);
}
#After
public void afterEachTest(){
channel.shutdownNow();
inprocessServer.stop();
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
}
The test does only test one of two methods, as it is just for illustration purposes. The other method can be tested accordingly.
See the RouteGuideExample for more information on how to test both server and client:
https://github.com/grpc/grpc-java/blob/master/examples/src/test/java/io/grpc/examples/routeguide/RouteGuideServerTest.java
I'd suggest using the InProcess transport. The InProcess transport is very lightweight but also is using much of the "real" code, so the behavior closely matches a real transport. If you also use directExecutor() for the Channel and Server then the test is essentially single-threaded and will be deterministic. (Although another thread would still be used for deadline handling.)
Although the question is for unit testing a service, InProcess is also great for unit testing a client.
I ended up with a solution to create a FakeStreamObserver that implements the StreamObserver interface.
The FakeStreamObserver is passed in to execute onNext, onCompleted etc.
I'm not sure if this is the best way or not.
I will insert snippets from the official gRPC examples. I have successfully created tests based on these HelloWorld example.
The HelloWorldService:
/*
* Copyright 2015, gRPC Authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.examples.helloworld;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import java.io.IOException;
import java.util.logging.Logger;
/**
* Server that manages startup/shutdown of a {#code Greeter} server.
*/
public class HelloWorldServer {
private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());
private Server server;
private void start() throws IOException {
/* The port on which the server should run */
int port = 50051;
server = ServerBuilder.forPort(port)
.addService(new GreeterImpl())
.build()
.start();
logger.info("Server started, listening on " + port);
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
// Use stderr here since the logger may have been reset by its JVM shutdown hook.
System.err.println("*** shutting down gRPC server since JVM is shutting down");
HelloWorldServer.this.stop();
System.err.println("*** server shut down");
}
});
}
private void stop() {
if (server != null) {
server.shutdown();
}
}
/**
* Await termination on the main thread since the grpc library uses daemon threads.
*/
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
/**
* Main launches the server from the command line.
*/
public static void main(String[] args) throws IOException, InterruptedException {
final HelloWorldServer server = new HelloWorldServer();
server.start();
server.blockUntilShutdown();
}
static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
#Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
}
And the test:
/*
* Copyright 2016, gRPC Authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.examples.helloworld;
import static org.junit.Assert.assertEquals;
import io.grpc.examples.helloworld.HelloWorldServer.GreeterImpl;
import io.grpc.testing.GrpcServerRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Unit tests for {#link HelloWorldServer}.
* For demonstrating how to write gRPC unit test only.
* Not intended to provide a high code coverage or to test every major usecase.
*
* <p>For more unit test examples see {#link io.grpc.examples.routeguide.RouteGuideClientTest} and
* {#link io.grpc.examples.routeguide.RouteGuideServerTest}.
*/
#RunWith(JUnit4.class)
public class HelloWorldServerTest {
/**
* This creates and starts an in-process server, and creates a client with an in-process channel.
* When the test is done, it also shuts down the in-process client and server.
*/
#Rule
public final GrpcServerRule grpcServerRule = new GrpcServerRule().directExecutor();
/**
* To test the server, make calls with a real stub using the in-process channel, and verify
* behaviors or state changes from the client side.
*/
#Test
public void greeterImpl_replyMessage() throws Exception {
// Add the service to the in-process server.
grpcServerRule.getServiceRegistry().addService(new GreeterImpl());
GreeterGrpc.GreeterBlockingStub blockingStub =
GreeterGrpc.newBlockingStub(grpcServerRule.getChannel());
String testName = "test name";
HelloReply reply = blockingStub.sayHello(HelloRequest.newBuilder().setName(testName).build());
assertEquals("Hello " + testName, reply.getMessage());
}
}
You can fin other examples, if you clone the examples repository as they describe it here:
https://grpc.io/docs/tutorials/basic/java.html
I hope it will help you, too.
Br,
Renato
#RunWith(JUnit4.class)
public class HelloWorldServerTest {
/**
* This rule manages automatic graceful shutdown for the registered servers and channels at the
* end of test.
*/
#Rule
public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule();
/**
* To test the server, make calls with a real stub using the in-process channel, and verify
* behaviors or state changes from the client side.
*/
#Test
public void greeterImpl_replyMessage() throws Exception {
// Generate a unique in-process server name.
String serverName = InProcessServerBuilder.generateName();
// Create a server, add service, start, and register for automatic graceful shutdown.
grpcCleanup.register(InProcessServerBuilder
.forName(serverName).directExecutor().addService(new GreeterImpl()).build().start());
GreeterGrpc.GreeterBlockingStub blockingStub = GreeterGrpc.newBlockingStub(
// Create a client channel and register for automatic graceful shutdown.
grpcCleanup.register(InProcessChannelBuilder.forName(serverName).directExecutor().build()));
HelloReply reply =
blockingStub.sayHello(HelloRequest.newBuilder().setName( "test name").build());
assertEquals("Hello test name", reply.getMessage());
}
}
https://github.com/grpc/grpc-java/blob/master/examples/src/test/java/io/grpc/examples/helloworld/HelloWorldServerTest.java
First, refactor the code so it's easier to unit test:
public class RpcTrackDataServiceImpl implements TrackDataServiceGrpc.TrackDataService {
#Override
public void getTracks(GetTracksRequest request, StreamObserver<GetTracksResponse> responseObserver) {
GetTracksResponse reply = getTracks(request);
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
#VisibleForTesting
GetTracksResponse getTracks(GetTracksRequest request) {
return GetTracksResponse
.newBuilder()
.addTracks(TrackInfo.newBuilder()
.setOwner("test")
.setTrackName("test")
.build())
.build();
}
}
Small tests can then be written for each (more easily if using Spring Boot):
public class UnitTest {
private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner();
#Configuration
public static class GetTracksConfiguration {
#Bean
public GetTracksService getTracksService() {
return new GetTracksService();
}
}
#Test
public void replyShouldBeSent() {
final GetTracksRequest request = GetTracksRequest.newBuilder().build();
final StreamObserver<GetTracksResponse> response = mock(StreamObserver.class);
applicationContextRunner
.withUserConfiguration(RequestTracksConfiguration.class)
.run(context -> {
assertThat(context)
.hasSingleBean(RequestTracksService.class);
context.getBean(RequestTracksService.class)
.getTracks(request, response);
verify(response, times(1)).onNext(any(GetTracksResponse.class));
verify(response, times(1)).onCompleted();
verify(response, never()).onError(any(Throwable.class));
});
}
#Test
public void shouldTestLogic {
assertLogicInFactoredOutMethodIsCorrect();
}
The larger test should then only test the startup and wiring:
#RunWith(SpringRunner.class)
#SpringBootTest(
classes = {GetTracksService.class}
)
#EnableAutoConfiguration
public class SmokeTest {
private GetTracksServiceGrpc.GetTracksServiceBlockingStub blockingStub;
#Test
public void springClientConnects() {
final GetTracksRequest request = GetTracksRequest.newBuilder()
.build();
assertNotNull(blockingStub.getTracks(request));
}
}
Note: The above code may not work OOTB since I've left out some annotations we use internally.
The major point is there's no need to pay for the cost of bringing up a server for unit tests that are meant to test logic.

WatchService loop running twice unless stepping through in debug mode

I am really new to WatchService and I am having a very interesting bug. When I run my code in normal mode(Run) it will loop through the for(Watch event: key1.pollEvents()) loop twice and create two google calander events but if I step through it using debug mode it only adds one event. I grabbed almost all of the code from online in an attempt to learn about how WatchService works. I don't really know what I am doing here so any help would be great. Here is my code
/*
* Copyright (c) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.api.services.samples.calendar.cmdline;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.java6.auth.oauth2.FileCredentialStore;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.DateTime;
import com.google.api.client.util.Lists;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.calendar.model.Calendar;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.Event.Reminders;
import com.google.api.services.calendar.model.EventDateTime;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import java.util.TimeZone;
/**
* #author Yaniv Inbar
*/
public class myCalendar {
/**
* Be sure to specify the name of your application. If the application name is {#code null} or
* blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0".
*/
private static final String APPLICATION_NAME = "";
/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static com.google.api.services.calendar.Calendar client;
static final java.util.List<Calendar> addedCalendarsUsingBatch = Lists.newArrayList();
/** Authorizes the installed application to access user's protected data. */
private static Credential authorize() throws Exception {
// load client secrets
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
new InputStreamReader(myCalendar.class.getResourceAsStream("/client_secrets.json")));
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://code.google.com/apis/console/?api=calendar "
+ "into calendar-cmdline-sample/src/main/resources/client_secrets.json");
System.exit(1);
}
// set up file credential store
FileCredentialStore credentialStore = new FileCredentialStore(
new File(System.getProperty("user.home"), ".credentials/calendar.json"), JSON_FACTORY);
// set up authorization code flow
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets,
Collections.singleton(CalendarScopes.CALENDAR)).setCredentialStore(credentialStore).build();
// authorize
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static void main(String[] args) throws IOException {
Path dir = Paths.get("C:\\Users\\kdevocht\\Dropbox\\Apps\\Attachments\\kjdevocht#gmail.com\\");
WatchService service = FileSystems.getDefault().newWatchService();
WatchKey key = dir.register(service, ENTRY_MODIFY);
System.out.println("Watching directory: "+dir.toString());
for(;;){
WatchKey key1;
try {
key1 = service.take();
} catch (InterruptedException x) {
break;
}
for (WatchEvent<?> event: key1.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == OVERFLOW) {
continue;
}
WatchEvent<Path> ev = (WatchEvent<Path>)event;
Path filename = ev.context();
Path child = dir.resolve(filename);
System.out.println("File: "+child.toString()+" modified.");
try{
try {
try {
// initialize the transport
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
// authorization
Credential credential = authorize();
// set up global Calendar instance
client = new com.google.api.services.calendar.Calendar.Builder(
HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(
APPLICATION_NAME).build();
// run commands
Calendar calendar = client.calendars().get("kjdevocht#gmail.com").execute();
addEvent(calendar, child.toString());
} catch (IOException e) {
System.err.println(e.getMessage());
}
} catch (Throwable t) {
t.printStackTrace();
}
//System.exit(1);;
}catch(Exception x){
x.printStackTrace();
}
}
boolean valid = key.reset();
if (!valid) {
break;
}
/* try {
Thread.sleep(5000);
} catch(InterruptedException e) {
} */
}
I thought it might have been a timing issue so I tried a sleep try catch but that did not work.
So it seems everything was working fine. I was using notepad++ to edit a file in the dir I was watching. After some research it appears that two modifications are made and so two events are logged. Some people have suggested storing the time stamp of the file and only react when it changes, this seems to filter out the multiple events. For me and what I was doing, I just changed to watching for a create event. This works great now with no problems