I have started the Docker containers and channels as per the "Build your First network" example
from the Hyperledger fabric docs .
I am trying to query a value from the ledger using Fabric Java SDK . The Fabric samples release version I am using is fabric-samples-release-1.0.
I get a certificate verification failed exception during channel initialize
Here is my Java code
public class javaSDKSample {
private static final Logger log = Logger.getLogger(HFJavaSDKBasicExample.class);
public static void main(String[] args) throws Exception {
// create fabric-ca client
HFCAClient caClient = getHfCaClient("http://{remotemachineURL}:7054", null);
// enroll or load admin
AppUser admin = getAdmin(caClient);
log.info(admin);
// register and enroll new user
// AppUser appUser = getUser(caClient, admin, "hfuser7");
// log.info(appUser);
// get HFC client instance
HFClient client = getHfClient();
// set user context
client.setUserContext(admin);
// get HFC channel using the client
Channel channel = getChannel(client);
log.info("Channel: " + channel.getName());
//createCar(client, channel, "CAR18", "MAKE7", "MODEL7", "BLACK", "JOHN", true);
// queryBlockChain(client);
}
/**
* Invoke blockchain query
*
* #param client The HF Client
* #throws ProposalException
* #throws InvalidArgumentException
*/
static void queryBlockChain(HFClient client) throws ProposalException, InvalidArgumentException {
// get channel instance from client
Channel channel = client.getChannel("mychannel");
// create chaincode request
QueryByChaincodeRequest qpr = client.newQueryProposalRequest();
// build cc id providing the chaincode name. Version is omitted here.
ChaincodeID fabcarCCId = ChaincodeID.newBuilder().setName("mycc").build();
qpr.setChaincodeID(fabcarCCId);
// CC function to be called
qpr.setFcn("query");
qpr.setArgs(new String[]{"a"});
Collection<ProposalResponse> res = channel.queryByChaincode(qpr);
// display response
for (ProposalResponse pres : res) {
String stringResponse = new String(pres.getChaincodeActionResponsePayload());
log.info(stringResponse);
}
}
static void createCar(HFClient client,Channel channel, String key, String make,String model,String color,String owner, Boolean doCommit)
throws Exception {
TransactionProposalRequest req = client.newTransactionProposalRequest();
ChaincodeID cid = ChaincodeID.newBuilder().setName("fabcar").build();
req.setChaincodeID(cid);
req.setFcn("createCar");
req.setArgs(new String[] { key, make,model,color,owner });
System.out.println("Executing for " + key);
Collection<ProposalResponse> resps = channel.sendTransactionProposal(req);
if (doCommit) {
channel.sendTransaction(resps);
}
}
/**
* Initialize and get HF channel
*
* #param client The HFC client
* #return Initialized channel
* #throws InvalidArgumentException
* #throws TransactionException
*/
static Channel getChannel(HFClient client) throws InvalidArgumentException, TransactionException {
// initialize channel
// peer name and endpoint in fabcar network
Properties peerProperties = new Properties();
peerProperties.setProperty("pemFile", "D:/FabricCert/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt");
peerProperties.setProperty("trustServerCertificate", "true"); //testing environment only NOT FOR PRODUCTION!
peerProperties.setProperty("hostnameOverride", "peer0.org1.example.com");
peerProperties.setProperty("sslProvider", "openSSL");
peerProperties.setProperty("negotiationType", "TLS");
peerProperties.put("grpc.NettyChannelBuilderOption.maxInboundMessageSize", 9000000);
Peer peer = client.newPeer("peer0.org1.example.com", "grpcs://{remotemachineURL}:7051");
// eventhub name and endpoint in fabcar network
final Properties eventHubProperties = new Properties();
eventHubProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[] {5L, TimeUnit.MINUTES});
eventHubProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[] {8L, TimeUnit.SECONDS});
EventHub eventHub = client.newEventHub("eventhub01", "grpcs://{remotemachineURL}:7053",eventHubProperties);
// orderer name and endpoint in fabcar network
Properties ordererProperties = new Properties();
ordererProperties.setProperty("pemFile", "D:/FabricCert/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt");
ordererProperties.setProperty("trustServerCertificate", "true"); //testing environment only NOT FOR PRODUCTION!
ordererProperties.setProperty("hostnameOverride", "orderer.example.com");
ordererProperties.setProperty("sslProvider", "openSSL");
ordererProperties.setProperty("negotiationType", "TLS");
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[] {5L, TimeUnit.MINUTES});
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[] {8L, TimeUnit.SECONDS});
Orderer orderer = client.newOrderer("orderer.example.com", "grpcs://{remotemachineURL}:7050");
// channel name in fabcar network
Channel channel = client.newChannel("mychannel");
channel.addPeer(peer);
channel.addEventHub(eventHub);
channel.addOrderer(orderer);
channel.initialize();
return channel;
}
/**
* Create new HLF client
*
* #return new HLF client instance. Never null.
* #throws CryptoException
* #throws InvalidArgumentException
*/
static HFClient getHfClient() throws Exception {
// initialize default cryptosuite
CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
// setup the client
HFClient client = HFClient.createNewInstance();
client.setCryptoSuite(cryptoSuite);
return client;
}
/**
* Register and enroll user with userId.
* If AppUser object with the name already exist on fs it will be loaded and
* registration and enrollment will be skipped.
*
* #param caClient The fabric-ca client.
* #param registrar The registrar to be used.
* #param userId The user id.
* #return AppUser instance with userId, affiliation,mspId and enrollment set.
* #throws Exception
*/
static AppUser getUser(HFCAClient caClient, AppUser registrar, String userId) throws Exception {
AppUser appUser = tryDeserialize(userId);
System.out.println("appUser"+appUser);
if (appUser == null) {
RegistrationRequest rr = new RegistrationRequest(userId, "org1");
String enrollmentSecret = caClient.register(rr, registrar);
Enrollment enrollment = getEnrollment();
enrollment = caClient.enroll(userId, enrollmentSecret);
byte[] certFile = Base64.encodeBase64(enrollment.getCert().getBytes());
byte[] keyFile = Base64.encodeBase64(enrollment.getKey().toString().getBytes());
BufferedWriter bufferedWriter = null;
File myFile = new File("D:/keyfile.key");
// check if file exist, otherwise create the file before writing
if (!myFile.exists()) {
myFile.createNewFile();
}
Writer writer = new FileWriter(myFile);
bufferedWriter = new BufferedWriter(writer);
bufferedWriter.write(enrollment.getKey().toString());
bufferedWriter.close();
appUser = new AppUser(userId, "org1", "Org1MSP", enrollment);
serialize(appUser);
}
return appUser;
}
public static Enrollment getEnrollment() {
return new Enrollment() {
public PrivateKey getKey() {
PrivateKey privateKey = null;
try {
File privateKeyFile = findFileSk("D:/FabricCert/crypto-config/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp/keystore");
privateKey = getPrivateKeyFromBytes(IOUtils.toByteArray(new FileInputStream(privateKeyFile)));
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return privateKey;
}
public String getCert() {
String certificate = null;
try {
File certificateFile = new File("D:/FabricCert/crypto-config/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp/signcerts/Admin#org1.example.com-cert.pem");
certificate = new String(IOUtils.toByteArray(new FileInputStream(certificateFile)), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return certificate;
}
};
}
static PrivateKey getPrivateKeyFromBytes(byte[] data) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException {
final Reader pemReader = new StringReader(new String(data));
final PrivateKeyInfo pemPair;
try (PEMParser pemParser = new PEMParser(pemReader)) {
pemPair = (PrivateKeyInfo) pemParser.readObject();
}
PrivateKey privateKey = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getPrivateKey(pemPair);
return privateKey;
}
/**
* Enroll admin into fabric-ca using {#code admin/adminpw} credentials.
* If AppUser object already exist serialized on fs it will be loaded and
* new enrollment will not be executed.
*
* #param caClient The fabric-ca client
* #return AppUser instance with userid, affiliation, mspId and enrollment set
* #throws Exception
*/
static AppUser getAdmin(HFCAClient caClient) throws Exception {
AppUser admin = tryDeserialize("admin");
if (admin == null) {
Enrollment adminEnrollment = caClient.enroll("admin", "adminpw");
admin = new AppUser("admin", "org1", "Org1MSP", adminEnrollment);
serialize(admin);
}
return admin;
}
/**
* Get new fabric-ca client
*
* #param caUrl The fabric-ca-server endpoint url
* #param caClientProperties The fabri-ca client properties. Can be null.
* #return new client instance. never null.
* #throws Exception
*/
static HFCAClient getHfCaClient(String caUrl, Properties caClientProperties) throws Exception {
CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
HFCAClient caClient = HFCAClient.createNewInstance(caUrl, caClientProperties);
caClient.setCryptoSuite(cryptoSuite);
return caClient;
}
// user serialization and deserialization utility functions
// files are stored in the base directory
/**
* Serialize AppUser object to file
*
* #param appUser The object to be serialized
* #throws IOException
*/
static void serialize(AppUser appUser) throws IOException {
try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(
Paths.get(appUser.getName() + ".jso")))) {
oos.writeObject(appUser);
}
}
/**
* Deserialize AppUser object from file
*
* #param name The name of the user. Used to build file name ${name}.jso
* #return
* #throws Exception
*/
static AppUser tryDeserialize(String name) throws Exception {
if (Files.exists(Paths.get(name + ".jso"))) {
return deserialize(name);
}
return null;
}
static AppUser deserialize(String name) throws Exception {
try (ObjectInputStream decoder = new ObjectInputStream(
Files.newInputStream(Paths.get(name + ".jso")))) {
return (AppUser) decoder.readObject();
}
}
static File findFileSk(String directorys) {
File directory = new File(directorys);
File[] matches = directory.listFiles((dir, name) -> name.endsWith("_sk"));
if (null == matches) {
throw new RuntimeException(format("Matches returned null does %s directory exist?", directory.getAbsoluteFile().getName()));
}
if (matches.length != 1) {
throw new RuntimeException(format("Expected in %s only 1 sk file but found %d", directory.getAbsoluteFile().getName(), matches.length));
}
return matches[0];
}}
And this is my error trace
DEBUG ReferenceCountedOpenSslContext - verification of certificate failed
java.security.cert.CertificateException: No subject alternative DNS name matching {remotemachineURL} found.
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:191)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:93)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:252)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
at io.netty.handler.ssl.ReferenceCountedOpenSslClientContext$ExtendedTrustManagerVerifyCallback.verify(ReferenceCountedOpenSslClientContext.java:223)
at io.netty.handler.ssl.ReferenceCountedOpenSslContext$AbstractCertificateVerifier.verify(ReferenceCountedOpenSslContext.java:606)
at org.apache.tomcat.jni.SSL.readFromSSL(Native Method)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.readPlaintextData(ReferenceCountedOpenSslEngine.java:470)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:927)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1033)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1076)
at io.netty.handler.ssl.SslHandler$SslEngineType$1.unwrap(SslHandler.java:206)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1117)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1039)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:129)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:642)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:565)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:479)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
at java.lang.Thread.run(Thread.java:745)
I am trying to initialize "mychannel" with peer0 from org1 and orderer and query for a value from the "byfn" network .
Please ignore extra code if any or the comments .
Thanks
Code worked , apparently there was some problem with the Enrollment .
I had used a bad certificate . Changed certificate for enrollment and it worked
Solved .Thanks
Related
Not able to download google sheet from google drive. Facing 403 Insufficient Permission issue.
Please check below code.
public class Quickstart {
/** Application name. */
private static final String APPLICATION_NAME = "Drive API Java Quickstart";
/** Directory to store user credentials for this application. */
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"),
".credentials/drive-java-quickstart");
/** Global instance of the {#link FileDataStoreFactory}. */
private static FileDataStoreFactory DATA_STORE_FACTORY;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT;
/**
* Global instance of the scopes required by this quickstart.
*
* If modifying these scopes, delete your previously saved credentials at
* ~/.credentials/drive-java-quickstart
*/
private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE_METADATA_READONLY);
static {
try {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
}
/**
* Creates an authorized Credential object.
*
* #return an authorized Credential object.
* #throws IOException
*/
public static Credential authorize() throws IOException {
// Load client secrets.
InputStream in = Quickstart.class.getResourceAsStream("/client_secret.json");
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
clientSecrets, SCOPES).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();
Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
/**
* Build and return an authorized Drive client service.
*
* #return an authorized Drive client service
* #throws IOException
*/
public static Drive getDriveService() throws IOException {
Credential credential = authorize();
return new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();
}
public static void main(String[] args) throws IOException {
// Build a new authorized API client service.
Drive service = getDriveService();
// Print the names and IDs for up to 10 files.
FileList result = service.files().list().setPageSize(10).setFields("nextPageToken, files(id, name)").execute();
List<File> files = result.getFiles();
if (files == null || files.size() == 0) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (File file : files) {
System.out.printf("%s (%s)\n", file.getName(), file.getId());
}
}
downloadFile(service, "1l0dX1hOdk0xX5T2ruqnci-75sMwziwiih9BFGX6DcdA");
}
private static void downloadFile(Drive service, String fileId) {
try {
File file = service.files().get(fileId).execute();
System.out.println("Title: " + file.getName());
System.out.println("Description: " + file.getDescription());
System.out.println("MIME type: " + file.getMimeType());
OutputStream outputStream = new ByteArrayOutputStream();
service.files().export(fileId, "application/x-vnd.oasis.opendocument.spreadsheet")
.executeMediaAndDownloadTo(outputStream);
} catch (IOException e) {
System.out.println("An error occurred: " + e);
}
}
}
**Output:**
403 error is displayed after executing above code. Please check below output of above code.
Credentials saved to /home/nikhil/.credentials/drive-java-quickstart
Files:
nikhil (1zNmRFWe_HABvhP_HukQIcOVdUoLllKB49RpPK3_XXn4)
Test Sheet (1l0dX1hOdk0xX5T2ruqnci-75sMwziwiih9BFGX6DcdA)
Getting started (0Bx8dATp9NaeXc3RhcnRlcl9maWxlX2Rhc2hlclYw)
Title: Test Sheet
Description: null
MIME type: application/vnd.google-apps.spreadsheet
An error occurred: com.google.api.client.http.HttpResponseException: 403
Forbidden
{
"error": {
"errors": [
{
"domain": "global",
"reason": "insufficientPermissions",
"message": "Insufficient Permission"
}
],
"code": 403,
"message": "Insufficient Permission"
}
}
Change the scope and data store directory.
private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE);
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"),
".credentials/drive-java-quickstart.json");
Added File path for saving the file to local machine.
public static void initialMethod() throws IOException {
// Build a new authorized API client service.
Drive service = getDriveService();
downloadFile(service, "1JYlTtznsCll16upwIIbgXjqDvjsAFO5krSiGjvciO70");
}
private static void downloadFile(Drive service, String fileId) {
try {
File file = service.files().get(fileId).execute();
System.out.println("Title: " + file.getName());
System.out.println("Description: " + file.getDescription());
System.out.println("MIME type: " + file.getMimeType());
OutputStream outputStream = new FileOutputStream(new java.io.File(Constant.DRIVE_EXCEL_PATH + "Test.xlsx"));
service.files().export(fileId, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
.executeMediaAndDownloadTo(outputStream);
System.out.println(outputStream);
} catch (IOException e) {
System.out.println("An error occurred: " + e);
} catch (Exception e) {
System.out.println("An error occurred: " + e);
}
}
Above code helps for downloading file from google drive.
I'm having trouble using the firebase-server-sdk with java, and verifying tokens server side. I have a rest controller setup to take a token from a client, then I run the following code.
FirebaseAuthVerifier.java
#Service
public class FirebaseAuthVerifier implements AuthVerifier {
Logger logger = LoggerFactory.getLogger(this.getClass());
public boolean verify(AuthToken token) throws GeneralSecurityException, IOException {
Task<FirebaseToken> fbTask = FirebaseAuth.getInstance().verifyIdToken(token.getTokenId());
fbTask.getResult();
return fbTask.isSuccessful();
}
}
FirebaseAuthController
#RestController
#RequestMapping("/api/firebase/auth")
public class FirebaseAuthController {
#Autowired
private FirebaseAuthVerifier glAuthVerifier;
#ResponseBody
#CrossOrigin(origins = "http://localhost:3000")
#RequestMapping(value = "/verify", method = RequestMethod.POST, headers = "Content-Type=application/json", consumes = "application/json", produces = "application/json")
public ResponseEntity<AuthTokenVerification> verify(#RequestBody GoogleAuthToken glAuthToken) throws GeneralSecurityException, IOException {
// init return
AuthTokenVerification glAuthTokenVerification = new GoogleAuthTokenVerification();
// verify token
boolean isVerified = this.glAuthVerifier.verify(glAuthToken);
glAuthTokenVerification.setIsVerified(isVerified);
// return json response
ResponseEntity<AuthTokenVerification> response = new ResponseEntity<>(glAuthTokenVerification, HttpStatus.OK);
return response;
}
}
but I receive an exception
java.lang.IllegalStateException: Task is not yet complete
I'm trying to do something simple here, but I'm not sure how to have java wait for completion here.
Using custom jwt id token validation.
#Service
public class FirebaseAuthVerifier implements AuthVerifier {
private static final Logger logger = LoggerFactory.getLogger(FirebaseAuthVerifier.class);
private static final String pubKeyUrl = "https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com";
/**
*
* #param token
* #return
* #throws GeneralSecurityException
* #throws IOException
*/
public boolean verify(AuthToken token) throws GeneralSecurityException, IOException {
// get public keys
JsonObject publicKeys = getPublicKeysJson();
// verify count
int size = publicKeys.entrySet().size();
int count = 0;
// get json object as map
// loop map of keys finding one that verifies
for (Map.Entry<String, JsonElement> entry: publicKeys.entrySet()) {
// log
logger.info("attempting jwt id token validation with: ");
try {
// trying next key
count++;
// get public key
PublicKey publicKey = getPublicKey(entry);
// validate claim set
Jwts.parser().setSigningKey(publicKey).parse(token.getTokenId());
// success, we can return
return true;
} catch(Exception e) {
// log
logger.info("Firebase id token verification error: ");
logger.info(e.getMessage());
// claims may have been tampered with
// if this is the last key, return false
if (count == size) {
return false;
}
}
}
// no jwt exceptions
return true;
}
/**
*
* #param entry
* #return
* #throws GeneralSecurityException
*/
private PublicKey getPublicKey(Map.Entry<String, JsonElement> entry) throws GeneralSecurityException, IOException {
String publicKeyPem = entry.getValue().getAsString()
.replaceAll("-----BEGIN (.*)-----", "")
.replaceAll("-----END (.*)----", "")
.replaceAll("\r\n", "")
.replaceAll("\n", "")
.trim();
logger.info(publicKeyPem);
// generate x509 cert
InputStream inputStream = new ByteArrayInputStream(entry.getValue().getAsString().getBytes("UTF-8"));
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(inputStream);
return cert.getPublicKey();
}
/**
*
* #return
* #throws IOException
*/
private JsonObject getPublicKeysJson() throws IOException {
// get public keys
URI uri = URI.create(pubKeyUrl);
GenericUrl url = new GenericUrl(uri);
HttpTransport http = new NetHttpTransport();
HttpResponse response = http.createRequestFactory().buildGetRequest(url).execute();
// store json from request
String json = response.parseAsString();
// disconnect
response.disconnect();
// parse json to object
JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
return jsonObject;
}
}
I actually have a problem, I want to know how to recover an image URL with his key in the Google Cloud Storage, here is the code.
StorageUtils.java
public class StorageUtils {
public static Storage storage;
private static final String DATETIME_FORMAT = "yyyyMMdd_HHmmss";
private static final String CAMERA_FILENAME_PREFIX = "IMG_";
/**
* Uploads a file to a bucket. Filename and content type will be based on
* the original file
* #param bucketName
* Bucket where file will be uploaded
* #param filePath
* Absolute path of the file to upload
* #throws Exception
*/
public static void uploadFile(String bucketName, String filePath)throws Exception {
Storage storage = getStorage();
String timeStamp = new SimpleDateFormat(DATETIME_FORMAT).format(new Date());
String imageFileName = CAMERA_FILENAME_PREFIX + timeStamp;
StorageObject object = new StorageObject();
object.setBucket(bucketName);
File file = new File(filePath);
InputStream stream = new FileInputStream(file);
try {
String contentType = URLConnection
.guessContentTypeFromStream(stream);
InputStreamContent content = new InputStreamContent(contentType,
stream);
Storage.Objects.Insert insert = storage.objects().insert(
bucketName, null, content);
insert.setName(imageFileName + file.getName());
insert.execute();
/////
/////
} finally {
stream.close();
}
}
public static void downloadFile(String bucketName, String fileName, String destinationDirectory) throws Exception {
File directory = new File(destinationDirectory);
if(!directory.isDirectory()) {
throw new Exception("Provided destinationDirectory path is not a directory");
}
File file = new File(directory.getAbsolutePath() + "/" + fileName);
Storage storage = getStorage();
Storage.Objects.Get get = storage.objects().get(bucketName, fileName);
FileOutputStream stream = new FileOutputStream(file);
try{
get.executeMediaAndDownloadTo(stream);
} finally {
stream.close();
}
}
/**
* Deletes a file within a bucket
*
* #param bucketName
* Name of bucket that contains the file
* #param fileName
* The file to delete
* #throws Exception
*/
public static void deleteFile(String bucketName, String fileName) throws Exception {
Storage storage = getStorage();
storage.objects().delete(bucketName, fileName).execute();
}
/**
* Creates a bucket
*
* #param bucketName
* Name of bucket to create
* #throws Exception
*/
public static void createBucket(String bucketName) throws Exception {
Storage storage = getStorage();
Bucket bucket = new Bucket();
bucket.setName(bucketName);
storage.buckets().insert(StorageConstants.PROJECT_ID_PROPERTY, bucket).execute();
}
/**
* Deletes a bucket
*
* #param bucketName
* Name of bucket to delete
* #throws Exception
*/
public static void deleteBucket(String bucketName) throws Exception {
Storage storage = getStorage();
storage.buckets().delete(bucketName).execute();
}
/**
* Lists the objects in a bucket
*
* #param bucketName bucket name to list
* #return Array of object names
* #throws Exception
*/
public static List<String> listBucket(String bucketName) throws Exception {
Storage storage = getStorage();
List<String> list = new ArrayList<String>();
List<StorageObject> objects = storage.objects().list(bucketName).execute().getItems();
if(objects != null) {
for(StorageObject o : objects) {
list.add(o.getName());
}
}
return list;
}
/**
* List the buckets with the project
* (Project is configured in properties)
*
* #return
* #throws Exception
*/
public static List<String> listBuckets() throws Exception {
Storage storage = getStorage();
List<String> list = new ArrayList<String>();
List<Bucket> buckets = storage.buckets().list(StorageConstants.PROJECT_ID_PROPERTY).execute().getItems();
if(buckets != null) {
for(Bucket b : buckets) {
list.add(b.getName());
}
}
return list;
}
private static Storage getStorage() throws Exception {
if (storage == null) {
ApacheHttpTransport httpTransport = new ApacheHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
List<String> scopes = new ArrayList<String>();
scopes.add(StorageScopes.DEVSTORAGE_FULL_CONTROL);
Credential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(StorageConstants.ACCOUNT_ID_PROPERTY)
.setServiceAccountPrivateKeyFromP12File(getTempPkc12File())
.setServiceAccountScopes(scopes).build();
storage = new Storage.Builder(httpTransport, jsonFactory,
credential).setApplicationName(StorageConstants.APPLICATION_NAME_PROPERTY)
.build();
}
return storage;
}
private static File getTempPkc12File() throws IOException {
InputStream pkc12Stream = StorageConstants.CONTEXT.getAssets().open("key.p12");
File tempPkc12File = File.createTempFile("temp_pkc12_file", "p12");
OutputStream tempFileStream = new FileOutputStream(tempPkc12File);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = pkc12Stream.read(bytes)) != -1) {
tempFileStream.write(bytes, 0, read);
}
return tempPkc12File;
}
}
I downloaded the code from the below link for android which has option to send echo, broadcast as well as user notification message.
Link for Android
Then I tried to use many codes for server side without any success so I studied and wrote the below code for the server side which I have hosted on Tomcat Server and there is a servlet which activates the client.
public class CcsServlet extends HttpServlet
{
private static Logger logger = Logger.getLogger(CcsServlet.class.getName());
private static final String USERNAME = "855350893195" + "#gcm.googleapis.com";
private static final String PASSWORD = "AIzaSyA9DQTcggUtABVC9lnV_Xb5VEQ8iKBEaP4";//AIzaSyAxDKiYUkU8EvtOgaCeZMypVJpzcYgyjhw-server
public void init(ServletConfig config) throws ServletException
{
SmackCcsClient ccsManager = SmackCcsClient.getInstance();
try
{
ccsManager.connect(USERNAME,PASSWORD);
}
catch (Exception e)
{
logger.warning("Cannot connect to CCS server.");
e.printStackTrace();
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException{
}
}
Code for the SmackCcsClient
public class SmackCcsClient {
private static Logger log = LoggerFactory.getLogger(SmackCcsClient.class);
private static SmackCcsClient sInstance = null;
XMPPConnection connection;
ConnectionConfiguration config;
public SmackCcsClient() {
// Add GcmPacketExtension
ProviderManager.getInstance().addExtensionProvider(
GCMConstants.GCM_ELEMENT_NAME,
GCMConstants.GCM_NAMESPACE,
new PacketExtensionProvider() {
#Override
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
String json = parser.nextText();
GcmPacketExtension packet = new GcmPacketExtension(json);
return packet;
}
});
}
/**
* Returns a random message id to uniquely identify a message.
*
*/
public String getRandomMessageId() {
return UUID.randomUUID().toString();
}
/**
* Sends a downstream GCM message.
*/
public void send(String jsonRequest) {
Packet request = new GcmPacketExtension(jsonRequest).toPacket();
connection.sendPacket(request);
}
public static SmackCcsClient getInstance()
{
if (sInstance == null)
sInstance = new SmackCcsClient();
return sInstance;
}
/**
* Handles an upstream data message from a device application.
*
* <p>
* This sample echo server sends an echo message back to the device.
* Subclasses should override this method to process an upstream message.
*/
public void handleIncomingDataMessage(Map<String, Object> jsonObject) {
String from = jsonObject.get("from").toString();
// PackageName of the application that sent this message.
String category = jsonObject.get("category").toString();
// Use the packageName as the collapseKey in the echo packet
String collapseKey = "echo:CollapseKey";
#SuppressWarnings("unchecked")
Map<String, String> payload = (Map<String, String>) jsonObject.get("data");
payload.put("ECHO", "Application: " + category);
// Send an ECHO response back
String echo = createJsonMessage(from, getRandomMessageId(), payload, collapseKey, null, false);
send(echo);
}
/**
* Handles an ACK.
*
* <p>
* By default, it only logs a INFO message, but subclasses could override it
* to properly handle ACKS.
*/
public void handleAckReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
log.debug("handleAckReceipt from: {}, messageId: {}", from, messageId);
}
/**
* Handles a NACK.
*
* <p>
* By default, it only logs a INFO message, but subclasses could override it
* to properly handle NACKS.
*/
public void handleNackReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
log.debug("handleNackReceipt() from: {}, messageId: {}",from, messageId);
}
/**
* Creates a JSON encoded GCM message.
*
* #param to
* RegistrationId of the target device (Required).
* #param messageId
* Unique messageId for which CCS will send an "ack/nack"
* (Required).
* #param payload
* Message content intended for the application. (Optional).
* #param collapseKey
* GCM collapse_key parameter (Optional).
* #param timeToLive
* GCM time_to_live parameter (Optional).
* #param delayWhileIdle
* GCM delay_while_idle parameter (Optional).
* #return JSON encoded GCM message.
*/
public static String createJsonMessage(String to, String messageId,
Map<String, String> payload, String collapseKey, Long timeToLive,
Boolean delayWhileIdle) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("to", to);
if (collapseKey != null) {
message.put("collapse_key", collapseKey);
}
if (timeToLive != null) {
message.put("time_to_live", timeToLive);
}
if (delayWhileIdle != null && delayWhileIdle) {
message.put("delay_while_idle", true);
}
message.put("message_id", messageId);
message.put("data", payload);
return JSONValue.toJSONString(message);
}
/**
* Creates a JSON encoded ACK message for an upstream message received from
* an application.
*
* #param to
* RegistrationId of the device who sent the upstream message.
* #param messageId
* messageId of the upstream message to be acknowledged to CCS.
* #return JSON encoded ack.
*/
public static String createJsonAck(String to, String messageId) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("message_type", "ack");
message.put("to", to);
message.put("message_id", messageId);
return JSONValue.toJSONString(message);
}
/**
* Connects to GCM Cloud Connection Server using the supplied credentials.
*
* #param username
* GCM_SENDER_ID#gcm.googleapis.com
* #param password
* API Key
* #throws XMPPException
*/
public void connect(String username, String password) throws XMPPException {
config = new ConnectionConfiguration(GCMConstants.GCM_SERVER, GCMConstants.GCM_PORT);
config.setSecurityMode(SecurityMode.enabled);
config.setReconnectionAllowed(true);
config.setRosterLoadedAtLogin(false);
config.setSendPresence(false);
config.setSocketFactory(SSLSocketFactory.getDefault());
// NOTE: Set to true to launch a window with information about packets
// sent and received
config.setDebuggerEnabled(true);
// -Dsmack.debugEnabled=true
XMPPConnection.DEBUG_ENABLED = true;
connection = new XMPPConnection(config);
connection.connect();
//**code used to send downstream message**
String toRegId = "APA91bECAx_1rzceJbPwas5FyRGPmpYFvWSJ0hfUlT30DSsrsXmBC5W-VmYTI0p8Gg9VZh598iNBcVki-H1dloBnaETfvZlJUZskTxHKE7DoDAgapH_X_DJE3toyZwXS4SHIdt5lYLty6OU_tmAOTZN4n88jlmSaR2_MrNmY1HuAMlddMfqAr10";
String messageId = sInstance.getRandomMessageId();
Map<String, String> payload = new HashMap<String, String>();
payload.put("Hello", "World");
payload.put("CCS", "Dummy Message");
payload.put("EmbeddedMessageId", messageId);
String collapseKey = "sample";
Long timeToLive = 10000L;
Boolean delayWhileIdle = true;
sInstance.send(createJsonMessage(toRegId, messageId, payload,
collapseKey, timeToLive, delayWhileIdle));
connection.addConnectionListener(new ConnectionListener() {
#Override
public void reconnectionSuccessful() {
log.info("Reconnecting..");
}
#Override
public void reconnectionFailed(Exception e) {
log.info( "Reconnection failed.. ", e);
}
#Override
public void reconnectingIn(int seconds) {
log.info( "Reconnecting in %d secs", seconds);
}
#Override
public void connectionClosedOnError(Exception e) {
log.info( "Connection closed on error.");
}
#Override
public void connectionClosed() {
log.info("Connection closed.");
}
});
// Handle incoming packets
connection.addPacketListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
log.info( "Received: " + packet.toXML());
Message incomingMessage = (Message) packet;
GcmPacketExtension gcmPacket = (GcmPacketExtension) incomingMessage.getExtension(GCMConstants.GCM_NAMESPACE);
String json = gcmPacket.getJson();
try {
#SuppressWarnings("unchecked")
Map<String, Object> jsonObject = (Map<String, Object>) JSONValue
.parseWithException(json);
// present for "ack"/"nack", null otherwise
Object messageType = jsonObject.get("message_type");
if (messageType == null) {
// Normal upstream data message
handleIncomingDataMessage(jsonObject);
// Send ACK to CCS
String messageId = jsonObject.get("message_id")
.toString();
String from = jsonObject.get("from").toString();
String ack = createJsonAck(from, messageId);
send(ack);
} else if ("ack".equals(messageType.toString())) {
// Process Ack
handleAckReceipt(jsonObject);
} else if ("nack".equals(messageType.toString())) {
// Process Nack
handleNackReceipt(jsonObject);
} else {
// logger.log(Level.WARNING,
// "Unrecognized message type (%s)",
messageType.toString();
}
} catch (Exception e) {
// logger.log(Level.SEVERE, "Couldn't send echo.", e);
}
}
}, new PacketTypeFilter(Message.class));
// Log all outgoing packets
connection.addPacketWriterInterceptor(new PacketInterceptor() {
#Override
public void interceptPacket(Packet packet) {
log.info( "Sent: {0}", packet.toXML());
}
}, new PacketTypeFilter(Message.class));
connection.login(username, password);
}
}
Code for GcmPacketExtension
class GcmPacketExtension extends DefaultPacketExtension {
String json;
public GcmPacketExtension(String json) {
super(GCMConstants.GCM_ELEMENT_NAME, GCMConstants.GCM_NAMESPACE);
this.json = json;
}
public String getJson() {
return json;
}
#Override
public String toXML() {
return String.format("<%s xmlns=\"%s\">%s</%s>", GCMConstants.GCM_ELEMENT_NAME,
GCMConstants.GCM_NAMESPACE, json, GCMConstants.GCM_ELEMENT_NAME);
}
#SuppressWarnings("unused")
public Packet toPacket() {
return new Message() {
// Must override toXML() because it includes a <body>
#Override
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<message");
if (getXmlns() != null) {
buf.append(" xmlns=\"").append(getXmlns()).append("\"");
}
if (getDefaultLanguage() != null) {
buf.append(" xml:lang=\"").append(getDefaultLanguage())
.append("\"");
}
if (getPacketID() != null) {
buf.append(" id=\"").append(getPacketID()).append("\"");
}
if (getTo() != null) {
buf.append(" to=\"")
.append(StringUtils.escapeForXML(getTo()))
.append("\"");
}
if (getFrom() != null) {
buf.append(" from=\"")
.append(StringUtils.escapeForXML(getFrom()))
.append("\"");
}
buf.append(">");
buf.append(GcmPacketExtension.this.toXML());
buf.append("</message>");
return buf.toString();
}
};
}
}
Code for GcmConstants
public class GCMConstants {
public static final String GCM_SERVER = "gcm.googleapis.com";
public static final int GCM_PORT = 5235;
public static final String GCM_ELEMENT_NAME = "gcm";
public static final String GCM_NAMESPACE = "google:mobile:data";
}
Now when I try to send a downstream message using the code in connect that does not reach the device which device id I have given or Echo message from device also does not echoed by server.
Is it required to sign up thing for CCS required because I have already signed up, however did not get any response.
Second question is why neither of the communication is working.
Now I have cleared up all the issues and now my servlet is running and making a connection however it is returning "No Response from the server", which I am getting as exception while connecting.
when taking the code below for sending a message to a device with using smack libary 3.3.0
Getting an error
SASL authentication PLAIN failed: text:
at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:342)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:221)
at org.jivesoftware.smack.Connection.login(Connection.java:366)
at com.test.xmpp.SmackCcsClient.connect(SmackCcsClient.java:335)
at com.test.xmpp.SmackCcsClient.main(SmackCcsClient.java:345)
When switching to HTTP server side, the messaging is working
/**
* Sample Smack implementation of a client for GCM Cloud Connection Server.
*
* <p>For illustration purposes only.
*/
public class SmackCcsClient {
Logger logger = Logger.getLogger("SmackCcsClient");
public static final String GCM_SERVER = "gcm.googleapis.com";
public static final int GCM_PORT = 5235;
public static final String GCM_ELEMENT_NAME = "gcm";
public static final String GCM_NAMESPACE = "google:mobile:data";
static Random random = new Random();
XMPPConnection connection;
ConnectionConfiguration config;
/**
* XMPP Packet Extension for GCM Cloud Connection Server.
*/
class GcmPacketExtension extends DefaultPacketExtension {
String json;
public GcmPacketExtension(String json) {
super(GCM_ELEMENT_NAME, GCM_NAMESPACE);
this.json = json;
}
public String getJson() {
return json;
}
#Override
public String toXML() {
return String.format("<%s xmlns=\"%s\">%s</%s>", GCM_ELEMENT_NAME,
GCM_NAMESPACE, json, GCM_ELEMENT_NAME);
}
#SuppressWarnings("unused")
public Packet toPacket() {
return new Message() {
// Must override toXML() because it includes a <body>
#Override
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<message");
if (getXmlns() != null) {
buf.append(" xmlns=\"").append(getXmlns()).append("\"");
}
if (getLanguage() != null) {
buf.append(" xml:lang=\"").append(getLanguage()).append("\"");
}
if (getPacketID() != null) {
buf.append(" id=\"").append(getPacketID()).append("\"");
}
if (getTo() != null) {
buf.append(" to=\"").append(StringUtils.escapeForXML(getTo())).append("\"");
}
if (getFrom() != null) {
buf.append(" from=\"").append(StringUtils.escapeForXML(getFrom())).append("\"");
}
buf.append(">");
buf.append(GcmPacketExtension.this.toXML());
buf.append("</message>");
return buf.toString();
}
};
}
}
public SmackCcsClient() {
// Add GcmPacketExtension
ProviderManager.getInstance().addExtensionProvider(GCM_ELEMENT_NAME,
GCM_NAMESPACE, new PacketExtensionProvider() {
#Override
public PacketExtension parseExtension(XmlPullParser parser)
throws Exception {
String json = parser.nextText();
GcmPacketExtension packet = new GcmPacketExtension(json);
return packet;
}
});
}
/**
* Returns a random message id to uniquely identify a message.
*
* <p>Note:
* This is generated by a pseudo random number generator for illustration purpose,
* and is not guaranteed to be unique.
*
*/
public String getRandomMessageId() {
return "m-" + Long.toString(random.nextLong());
}
/**
* Sends a downstream GCM message.
*/
public void send(String jsonRequest) {
Packet request = new GcmPacketExtension(jsonRequest).toPacket();
connection.sendPacket(request);
}
/**
* Handles an upstream data message from a device application.
*
* <p>This sample echo server sends an echo message back to the device.
* Subclasses should override this method to process an upstream message.
*/
public void handleIncomingDataMessage(Map<String, Object> jsonObject) {
String from = jsonObject.get("from").toString();
// PackageName of the application that sent this message.
String category = jsonObject.get("category").toString();
// Use the packageName as the collapseKey in the echo packet
String collapseKey = "echo:CollapseKey";
#SuppressWarnings("unchecked")
Map<String, String> payload = (Map<String, String>) jsonObject.get("data");
payload.put("ECHO", "Application: " + category);
// Send an ECHO response back
String echo = createJsonMessage(from, getRandomMessageId(), payload, collapseKey, null, false);
send(echo);
}
/**
* Handles an ACK.
*
* <p>By default, it only logs a INFO message, but subclasses could override it to
* properly handle ACKS.
*/
public void handleAckReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
logger.log(Level.INFO, "handleAckReceipt() from: " + from + ", messageId: " + messageId);
}
/**
* Handles a NACK.
*
* <p>By default, it only logs a INFO message, but subclasses could override it to
* properly handle NACKS.
*/
public void handleNackReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
logger.log(Level.INFO, "handleNackReceipt() from: " + from + ", messageId: " + messageId);
}
/**
* Creates a JSON encoded GCM message.
*
* #param to RegistrationId of the target device (Required).
* #param messageId Unique messageId for which CCS will send an "ack/nack" (Required).
* #param payload Message content intended for the application. (Optional).
* #param collapseKey GCM collapse_key parameter (Optional).
* #param timeToLive GCM time_to_live parameter (Optional).
* #param delayWhileIdle GCM delay_while_idle parameter (Optional).
* #return JSON encoded GCM message.
*/
public static String createJsonMessage(String to, String messageId, Map<String, String> payload,
String collapseKey, Long timeToLive, Boolean delayWhileIdle) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("to", to);
if (collapseKey != null) {
message.put("collapse_key", collapseKey);
}
if (timeToLive != null) {
message.put("time_to_live", timeToLive);
}
if (delayWhileIdle != null && delayWhileIdle) {
message.put("delay_while_idle", true);
}
message.put("message_id", messageId);
message.put("data", payload);
return JSONValue.toJSONString(message);
}
/**
* Creates a JSON encoded ACK message for an upstream message received from an application.
*
* #param to RegistrationId of the device who sent the upstream message.
* #param messageId messageId of the upstream message to be acknowledged to CCS.
* #return JSON encoded ack.
*/
public static String createJsonAck(String to, String messageId) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("message_type", "ack");
message.put("to", to);
message.put("message_id", messageId);
return JSONValue.toJSONString(message);
}
/**
* Connects to GCM Cloud Connection Server using the supplied credentials.
*
* #param username GCM_SENDER_ID#gcm.googleapis.com
* #param password API Key
* #throws XMPPException
*/
public void connect(String username, String password) throws XMPPException {
config = new ConnectionConfiguration(GCM_SERVER, GCM_PORT);
config.setSecurityMode(SecurityMode.enabled);
config.setReconnectionAllowed(true);
config.setRosterLoadedAtLogin(false);
config.setSendPresence(false);
config.setSocketFactory(SSLSocketFactory.getDefault());
// NOTE: Set to true to launch a window with information about packets sent and received
config.setDebuggerEnabled(true);
// -Dsmack.debugEnabled=true
XMPPConnection.DEBUG_ENABLED = true;
connection = new XMPPConnection(config);
connection.connect();
connection.addConnectionListener(new ConnectionListener() {
#Override
public void reconnectionSuccessful() {
logger.info("Reconnecting..");
}
#Override
public void reconnectionFailed(Exception e) {
logger.log(Level.INFO, "Reconnection failed.. ", e);
}
#Override
public void reconnectingIn(int seconds) {
logger.log(Level.INFO, "Reconnecting in %d secs", seconds);
}
#Override
public void connectionClosedOnError(Exception e) {
logger.log(Level.INFO, "Connection closed on error.");
}
#Override
public void connectionClosed() {
logger.info("Connection closed.");
}
});
// Handle incoming packets
connection.addPacketListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
logger.log(Level.INFO, "Received: " + packet.toXML());
Message incomingMessage = (Message) packet;
GcmPacketExtension gcmPacket =
(GcmPacketExtension) incomingMessage.getExtension(GCM_NAMESPACE);
String json = gcmPacket.getJson();
try {
#SuppressWarnings("unchecked")
Map<String, Object> jsonObject =
(Map<String, Object>) JSONValue.parseWithException(json);
// present for "ack"/"nack", null otherwise
Object messageType = jsonObject.get("message_type");
if (messageType == null) {
// Normal upstream data message
handleIncomingDataMessage(jsonObject);
// Send ACK to CCS
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
String ack = createJsonAck(from, messageId);
send(ack);
} else if ("ack".equals(messageType.toString())) {
// Process Ack
handleAckReceipt(jsonObject);
} else if ("nack".equals(messageType.toString())) {
// Process Nack
handleNackReceipt(jsonObject);
} else {
logger.log(Level.WARNING, "Unrecognized message type (%s)",
messageType.toString());
}
} catch (ParseException e) {
logger.log(Level.SEVERE, "Error parsing JSON " + json, e);
} catch (Exception e) {
logger.log(Level.SEVERE, "Couldn't send echo.", e);
}
}
}, new PacketTypeFilter(Message.class));
// Log all outgoing packets
connection.addPacketInterceptor(new PacketInterceptor() {
#Override
public void interceptPacket(Packet packet) {
logger.log(Level.INFO, "Sent: {0}", packet.toXML());
}
}, new PacketTypeFilter(Message.class));
connection.login(username, password);
}
public static void main(String [] args) {
final String userName = "124079202908" + "#gcm.googleapis.com";
final String password = "AIzaSyAMt1y_xILk72wiQybuqVEdiq7uGXBEUhQ";
SmackCcsClient ccsClient = new SmackCcsClient();
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
Also I submitted a request for using the API over a week ago and didn't recieve a reply yet.
The problem is resolved. The issue was indeed that the project wasn't registered. I received an email from Google 2 weeks after asking for the API receiving confirmation.
The error in this case really should be improved and it would be nice if Google wrote approximately how long to receive the email.
Just wanted to update anyone else encountering the problem.
#user2679041 i guess you are saying right. I have register my gcm project id just today and i haven't receive any confirmation email yet. That's really annoying, who else is going to wait for a 2 weeks? I have saw few queries # stackoverflow that people says there request approved by google after 3 months too.
I have followed the this link
and its has a note saying :
After you have created your GCM enabled project in the API Console you must fill out this form and become a trial partner to use upstream messaging and user notifications via CCS. Access is limited to those that fill out the form. You will receive an email from Google informing you that you now have access; Google will also send you the address of an echo server that you can use to bounce messages back to your application.
So we might say Google has released beta version with limited no. of access.