/** * Gets license version 2 data for sign. * * @param lic GridGain license version 2. * @return Data for sign. */ public static byte[] getDataV2ForSign(GridLicenseV2 lic) { assert lic != null; try { return new SB() .a(lic.getVersion()) .a(lic.getId()) .a(lic.getIssueDate() != null ? U.format(lic.getIssueDate(), DATE_PTRN) : "") .a(lic.getIssueOrganization()) .a(lic.getUserOrganization()) .a(lic.getUserWww()) .a(lic.getUserEmail()) .a(lic.getUserName()) .a(lic.getLicenseNote()) .a(lic.getVersionRegexp()) .a(lic.getType()) .a(lic.getExpireDate() != null ? U.format(lic.getExpireDate(), DATE_PTRN) : "") .a(lic.getMeteringKey1()) .a(lic.getMeteringKey2()) .a(lic.getMaxCpus()) .a(lic.getMaxComputers()) .a(lic.getMaxNodes()) .a(lic.getMaxUpTime()) .toString() .getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { throw new GridRuntimeException(e); } }
/** * Decodes value from a given byte array to the object according to the flags given. * * @param flags Flags. * @param bytes Byte array to decode. * @return Decoded value. * @throws GridException If deserialization failed. */ private Object decodeObj(short flags, byte[] bytes) throws GridException { assert bytes != null; if ((flags & SERIALIZED_FLAG) != 0) return jdkMarshaller.unmarshal(new ByteArrayInputStream(bytes), null); int masked = flags & 0xff00; switch (masked) { case BOOLEAN_FLAG: return bytes[0] == '1'; case INT_FLAG: return U.bytesToInt(bytes, 0); case LONG_FLAG: return U.bytesToLong(bytes, 0); case DATE_FLAG: return new Date(U.bytesToLong(bytes, 0)); case BYTE_FLAG: return bytes[0]; case FLOAT_FLAG: return Float.intBitsToFloat(U.bytesToInt(bytes, 0)); case DOUBLE_FLAG: return Double.longBitsToDouble(U.bytesToLong(bytes, 0)); case BYTE_ARR_FLAG: return bytes; default: return new String(bytes); } }
/** * Processes unlock request. * * @param nodeId Sender node ID. * @param req Unlock request. */ @SuppressWarnings({"unchecked"}) private void processUnlockRequest(UUID nodeId, GridDistributedUnlockRequest req) { assert nodeId != null; try { ClassLoader ldr = ctx.deploy().globalLoader(); List<byte[]> keys = req.keyBytes(); for (byte[] keyBytes : keys) { K key = (K) U.unmarshal(ctx.marshaller(), new ByteArrayInputStream(keyBytes), ldr); while (true) { boolean created = false; GridDistributedCacheEntry<K, V> entry = peekexx(key); if (entry == null) { entry = entryexx(key); created = true; } try { entry.doneRemote( req.version(), req.version(), req.committedVersions(), req.rolledbackVersions()); // Note that we don't reorder completed versions here, // as there is no point to reorder relative to the version // we are about to remove. if (entry.removeLock(req.version())) { if (log.isDebugEnabled()) log.debug("Removed lock [lockId=" + req.version() + ", key=" + key + ']'); if (created && entry.markObsolete(req.version())) removeIfObsolete(entry.key()); } else if (log.isDebugEnabled()) log.debug( "Received unlock request for unknown candidate " + "(added to cancelled locks set): " + req); break; } catch (GridCacheEntryRemovedException ignored) { if (log.isDebugEnabled()) log.debug( "Received remove lock request for removed entry (will retry) [entry=" + entry + ", req=" + req + ']'); } } } } catch (GridException e) { U.error(log, "Failed to unmarshal unlock key (unlock will not be performed): " + req, e); } }
/** * Encodes given object to a byte array and returns flags that describe the type of serialized * object. * * @param obj Object to serialize. * @param out Output stream to which object should be written. * @return Serialization flags. * @throws GridException If JDK serialization failed. */ private int encodeObj(Object obj, ByteArrayOutputStream out) throws GridException { int flags = 0; byte[] data = null; if (obj instanceof String) { data = ((String) obj).getBytes(); } else if (obj instanceof Boolean) { data = new byte[] {(byte) ((Boolean) obj ? '1' : '0')}; flags |= BOOLEAN_FLAG; } else if (obj instanceof Integer) { data = U.intToBytes((Integer) obj); flags |= INT_FLAG; } else if (obj instanceof Long) { data = U.longToBytes((Long) obj); flags |= LONG_FLAG; } else if (obj instanceof Date) { data = U.longToBytes(((Date) obj).getTime()); flags |= DATE_FLAG; } else if (obj instanceof Byte) { data = new byte[] {(Byte) obj}; flags |= BYTE_FLAG; } else if (obj instanceof Float) { data = U.intToBytes(Float.floatToIntBits((Float) obj)); flags |= FLOAT_FLAG; } else if (obj instanceof Double) { data = U.longToBytes(Double.doubleToLongBits((Double) obj)); flags |= DOUBLE_FLAG; } else if (obj instanceof byte[]) { data = (byte[]) obj; flags |= BYTE_ARR_FLAG; } else { jdkMarshaller.marshal(obj, out); flags |= SERIALIZED_FLAG; } if (data != null) out.write(data, 0, data.length); return flags; }
/** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { super.readExternal(in); threadId = in.readLong(); commit = in.readBoolean(); invalidate = in.readBoolean(); reply = in.readBoolean(); futId = U.readGridUuid(in); commitVer = CU.readVersion(in); baseVer = CU.readVersion(in); writeEntries = U.readList(in); }
/** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { super.writeExternal(out); out.writeLong(threadId); out.writeBoolean(commit); out.writeBoolean(invalidate); out.writeBoolean(reply); U.writeGridUuid(out, futId); CU.writeVersion(out, commitVer); CU.writeVersion(out, baseVer); U.writeCollection(out, writeEntries); }
/** {@inheritDoc} */ @SuppressWarnings({"CatchGenericClass"}) @Override public final void run() { try { body(); } catch (InterruptedException e) { if (log.isDebugEnabled()) { log.debug("Caught interrupted exception: " + e); } } // Catch everything to make sure that it gets logged properly and // not to kill any threads from the underlying thread pool. catch (Throwable e) { U.error(log, "Runtime error caught during grid runnable execution: " + this, e); } finally { cleanup(); if (log.isDebugEnabled()) { if (isInterrupted()) { log.debug( "Grid runnable finished due to interruption without cancellation: " + getName()); } else { log.debug("Grid runnable finished normally: " + getName()); } } } }
/** Initializes future. */ @SuppressWarnings({"unchecked"}) void finish() { if (mappings != null) { finish(mappings.values()); markInitialized(); if (!isSync()) { boolean complete = true; for (GridFuture<?> f : pending()) // Mini-future in non-sync mode gets done when message gets sent. if (isMini(f) && !f.isDone()) complete = false; if (complete) onComplete(); } } else { assert !commit; try { tx.rollback(); } catch (GridException e) { U.error(log, "Failed to rollback empty transaction: " + tx, e); } markInitialized(); } }
/** {@inheritDoc} */ @SuppressWarnings({"unchecked"}) @Override public void listenAsync(@Nullable final GridInClosure<? super GridFuture<R>> lsnr) { if (lsnr != null) { checkValid(); boolean done; synchronized (mux) { done = this.done; if (!done) lsnrs.add(lsnr); } if (done) { try { if (syncNotify) notifyListener(lsnr); else ctx.closure() .runLocalSafe( new GPR() { @Override public void run() { notifyListener(lsnr); } }, true); } catch (IllegalStateException ignore) { U.warn( null, "Future notification will not proceed because grid is stopped: " + ctx.gridName()); } } } }
/** * @param nodeId Sender node ID. * @param msg Response to prepare request. */ private void processPrepareResponse(UUID nodeId, GridDistributedTxPrepareResponse<K, V> msg) { assert nodeId != null; assert msg != null; GridReplicatedTxLocal<K, V> tx = ctx.tm().tx(msg.version()); if (tx == null) { if (log.isDebugEnabled()) log.debug( "Received prepare response for non-existing transaction [senderNodeId=" + nodeId + ", res=" + msg + ']'); return; } GridReplicatedTxPrepareFuture<K, V> future = (GridReplicatedTxPrepareFuture<K, V>) tx.future(); if (future != null) future.onResult(nodeId, msg); else U.error( log, "Received prepare response for transaction with no future [res=" + msg + ", tx=" + tx + ']'); }
/** * Records deploy event. * * @param cls Deployed class. * @param clsLdr Class loader. * @param recordEvt Flag indicating whether to record events. */ @SuppressWarnings({"unchecked"}) private void recordDeployFailed(Class<?> cls, ClassLoader clsLdr, boolean recordEvt) { assert cls != null; assert clsLdr != null; boolean isTask = isTask(cls); String msg = "Failed to deploy " + (isTask ? "task" : "class") + " [cls=" + cls + ", clsLdr=" + clsLdr + ']'; if (recordEvt && ctx.event().isRecordable(isTask ? EVT_CLASS_DEPLOY_FAILED : EVT_TASK_DEPLOY_FAILED)) { String taskName = isTask ? U.getTaskName((Class<? extends GridTask<?, ?>>) cls) : null; GridDeploymentEvent evt = new GridDeploymentEvent(); evt.message(msg); evt.nodeId(ctx.localNodeId()); evt.type(isTask(cls) ? EVT_CLASS_DEPLOY_FAILED : EVT_TASK_DEPLOY_FAILED); evt.alias(taskName); ctx.event().record(evt); } if (log.isInfoEnabled()) { log.info(msg); } }
/** * Load classes from given file. File could be either directory or JAR file. * * @param clsLdr Class loader to load files. * @param file Either directory or JAR file which contains classes or references to them. * @return Set of found and loaded classes or empty set if file does not exist. * @throws GridSpiException Thrown if given JAR file references to none existed class or * IOException occurred during processing. */ static Set<Class<? extends GridTask<?, ?>>> getClasses(ClassLoader clsLdr, File file) throws GridSpiException { Set<Class<? extends GridTask<?, ?>>> rsrcs = new HashSet<Class<? extends GridTask<?, ?>>>(); if (file.exists() == false) { return rsrcs; } GridUriDeploymentFileResourceLoader fileRsrcLdr = new GridUriDeploymentFileResourceLoader(clsLdr, file); if (file.isDirectory()) { findResourcesInDirectory(fileRsrcLdr, file, rsrcs); } else { try { for (JarEntry entry : U.asIterable(new JarFile(file.getAbsolutePath()).entries())) { Class<? extends GridTask<?, ?>> rsrc = fileRsrcLdr.createResource(entry.getName(), false); if (rsrc != null) { rsrcs.add(rsrc); } } } catch (IOException e) { throw new GridSpiException( "Failed to discover classes in file: " + file.getAbsolutePath(), e); } } return rsrcs; }
/** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { super.writeExternal(out); assert futId != null; assert miniId != null; assert ver != null; U.writeGridUuid(out, futId); U.writeGridUuid(out, miniId); U.writeCollection(out, entries); U.writeIntCollection(out, invalidParts); CU.writeVersion(out, ver); out.writeObject(err); }
/** * @param bytes Bytes to unmarshal. * @param ldr Class loader. * @param <T> Type to unmarshal. * @return Unmarshalled value. * @throws GridException If unmarshal failed. */ @SuppressWarnings({"unchecked", "TypeMayBeWeakened"}) private <T> T unmarshal(GridSwapByteArray bytes, ClassLoader ldr) throws GridException { return (T) U.unmarshal( cctx.marshaller(), new ByteArrayInputStream(bytes.getArray(), bytes.getOffset(), bytes.getLength()), ldr); }
/** * Delegates to {@link #call()} method. * * <p>{@inheritDoc} * * @return {@inheritDoc} * @throws GridException {@inheritDoc} */ @Override public final Object execute() throws GridException { try { return call(); } catch (Throwable e) { throw U.cast(e); } }
/** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { super.writeExternal(out); out.writeLong(topVer); out.writeBoolean(implicitTx); out.writeBoolean(implicitSingleTx); out.writeBoolean(syncCommit); out.writeBoolean(syncRollback); out.writeObject(filterBytes); U.writeArray(out, dhtVers); assert miniId != null; U.writeGridUuid(out, miniId); }
/** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { super.readExternal(in); topVer = in.readLong(); implicitTx = in.readBoolean(); implicitSingleTx = in.readBoolean(); syncCommit = in.readBoolean(); syncRollback = in.readBoolean(); filterBytes = (byte[][]) in.readObject(); dhtVers = U.readArray(in, CU.versionArrayFactory()); miniId = U.readGridUuid(in); assert miniId != null; }
/** * @param nodeId Sender node ID. * @param msg Finish transaction response. */ private void processFinishResponse(UUID nodeId, GridDistributedTxFinishResponse<K, V> msg) { GridReplicatedTxCommitFuture<K, V> fut = (GridReplicatedTxCommitFuture<K, V>) ctx.mvcc().<GridCacheTx>future(msg.xid().id(), msg.futureId()); if (fut != null) fut.onResult(nodeId); else U.warn(log, "Received finish response for unknown transaction: " + msg); }
/** * Reconstructs object on demarshalling. * * @return Reconstructed object. * @throws ObjectStreamException Thrown in case of demarshalling error. */ private Object readResolve() throws ObjectStreamException { GridTuple2<GridCacheContext, String> t = stash.get(); try { return t.get1().dataStructures().sequence(t.get2(), 0L, false, false); } catch (GridException e) { throw U.withCause(new InvalidObjectException(e.getMessage()), e); } }
/** * Removes locks regardless of whether they are owned or not for given version and keys. * * @param ver Lock version. * @param keys Keys. */ @SuppressWarnings({"unchecked"}) public void removeLocks(GridCacheVersion ver, Collection<? extends K> keys) { if (keys.isEmpty()) return; Collection<GridRichNode> nodes = ctx.remoteNodes(keys); try { // Send request to remove from remote nodes. GridDistributedUnlockRequest<K, V> req = new GridDistributedUnlockRequest<K, V>(keys.size()); req.version(ver); for (K key : keys) { while (true) { GridDistributedCacheEntry<K, V> entry = peekexx(key); try { if (entry != null) { GridCacheMvccCandidate<K> cand = entry.candidate(ver); if (cand != null) { // Remove candidate from local node first. if (entry.removeLock(cand.version())) { // If there is only local node in this lock's topology, // then there is no reason to distribute the request. if (nodes.isEmpty()) continue; req.addKey(entry.key(), entry.getOrMarshalKeyBytes(), ctx); } } } break; } catch (GridCacheEntryRemovedException ignored) { if (log.isDebugEnabled()) log.debug( "Attempted to remove lock from removed entry (will retry) [rmvVer=" + ver + ", entry=" + entry + ']'); } } } if (nodes.isEmpty()) return; req.completedVersions(ctx.tm().committedVersions(ver), ctx.tm().rolledbackVersions(ver)); if (!req.keyBytes().isEmpty()) // We don't wait for reply to this message. ctx.io().safeSend(nodes, req, null); } catch (GridException ex) { U.error(log, "Failed to unlock the lock for keys: " + keys, ex); } }
/** {@inheritDoc} */ @Override public void start() throws GridException { ctxLdr = U.detectClassLoader(getClass()); spi.setListener(new LocalDeploymentListener()); if (log.isDebugEnabled()) { log.debug(startInfo()); } }
/** * Reconstructs object on demarshalling. * * @return Reconstructed object. * @throws ObjectStreamException Thrown in case of demarshalling error. */ @SuppressWarnings({"ConstantConditions"}) private Object readResolve() throws ObjectStreamException { GridTuple2<GridCacheContext, String> t = stash.get(); try { return t.get1().dataStructures().countDownLatch(t.get2(), 0, false, false); } catch (GridException e) { throw U.withCause(new InvalidObjectException(e.getMessage()), e); } }
/** * Delegates to {@link #apply()} method. * * <p>{@inheritDoc} * * @return {@inheritDoc} * @throws GridException {@inheritDoc} */ @Override public final Object execute() throws GridException { try { apply(); } catch (Throwable e) { throw U.cast(e); } return null; }
/** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { super.readExternal(in); futId = U.readGridUuid(in); miniId = U.readGridUuid(in); entries = U.readCollection(in); invalidParts = U.readIntSet(in); ver = CU.readVersion(in); err = (Throwable) in.readObject(); if (invalidParts == null) invalidParts = Collections.emptyList(); assert futId != null; assert miniId != null; assert ver != null; }
/** * Create signature for license version 2. * * @param key Private key. * @param lic License version 2. * @return Signature. * @throws GeneralSecurityException If any exception occurs while signature creation. */ public static String createSignatureV2(PrivateKey key, GridLicenseV2 lic) throws GeneralSecurityException { assert key != null; assert lic != null; byte[] data = getDataV2ForSign(lic); byte[] sign = createSignature(SIGN_ALG, PRV, key, data); return U.byteArray2HexString(sign); }
/** * Verifies license version 2 signature. * * @param key Public key. * @param lic License version 2. * @return {@code true} if signature was verified, {@code false} - otherwise. * @throws GeneralSecurityException If any exception occurs while verifying. */ public static boolean verifySignatureV2(PublicKey key, GridLicenseV2 lic) throws GeneralSecurityException { assert key != null; assert lic != null; byte[] data = getDataV2ForSign(lic); byte[] sign = U.hexString2ByteArray(lic.getSignature()); return verifySignature(SIGN_ALG, PRV, key, data, sign); }
/** * Adds new participant to deployment. * * @param dep Shared deployment. * @param meta Request metadata. * @return {@code True} if participant was added. */ private boolean addParticipant(SharedDeployment dep, GridDeploymentMetadata meta) { assert dep != null; assert meta != null; assert Thread.holdsLock(mux); if (!checkModeMatch(dep, meta)) return false; if (meta.participants() != null) { for (Map.Entry<UUID, GridTuple2<GridUuid, Long>> e : meta.participants().entrySet()) { dep.addParticipant(e.getKey(), e.getValue().get1(), e.getValue().get2()); if (log.isDebugEnabled()) log.debug( "Added new participant [nodeId=" + e.getKey() + ", clsLdrId=" + e.getValue().get1() + ", seqNum=" + e.getValue().get2() + ']'); } } if (dep.deployMode() == CONTINUOUS || meta.participants() == null) { if (!dep.addParticipant(meta.senderNodeId(), meta.classLoaderId(), meta.sequenceNumber())) { U.warn( log, "Failed to create shared mode deployment " + "(requested class loader was already undeployed, did sender node leave grid?) " + "[clsLdrId=" + meta.classLoaderId() + ", senderNodeId=" + meta.senderNodeId() + ']'); return false; } if (log.isDebugEnabled()) log.debug( "Added new participant [nodeId=" + meta.senderNodeId() + ", clsLdrId=" + meta.classLoaderId() + ", seqNum=" + meta.sequenceNumber() + ']'); } return true; }
/** * Converts given input stream expecting XML inside to {@link GridUriDeploymentSpringDocument}. * * <p>This is a workaround for the {@link InputStreamResource} which does not work properly. * * @param in Input stream with XML. * @param log Logger * @return Grid wrapper for the input stream. * @throws GridSpiException Thrown if incoming input stream could not be read or parsed by {@code * Spring} {@link XmlBeanFactory}. * @see XmlBeanFactory */ static GridUriDeploymentSpringDocument parseTasksDocument(InputStream in, GridLogger log) throws GridSpiException { assert in != null; // Note: use ByteArrayResource instead of InputStreamResource because InputStreamResource // doesn't work. ByteArrayOutputStream out = new ByteArrayOutputStream(); try { U.copy(in, out); XmlBeanFactory factory = new XmlBeanFactory(new ByteArrayResource(out.toByteArray())); return new GridUriDeploymentSpringDocument(factory); } catch (BeansException e) { throw new GridSpiException("Failed to parse spring XML file.", e); } catch (IOException e) { throw new GridSpiException("Failed to parse spring XML file.", e); } finally { U.close(out, log); } }
/** * Notifies single listener. * * @param lsnr Listener. */ private void notifyListener(GridInClosure<? super GridFuture<R>> lsnr) { assert lsnr != null; try { lsnr.apply(this); } catch (IllegalStateException ignore) { U.warn( null, "Failed to notify listener (grid is stopped) [grid=" + ctx.gridName() + ", lsnr=" + lsnr + ']'); } catch (RuntimeException e) { U.error(log, "Failed to notify listener: " + lsnr, e); throw e; } catch (Error e) { U.error(log, "Failed to notify listener: " + lsnr, e); throw e; } }
/** {@inheritDoc} */ @Override public String toString() { return S.toString( GridDiscoveryEvent.class, this, "nodeId8", U.id8(nodeId()), "msg", message(), "type", name(), "tstamp", timestamp()); }